MySQL的列类型
<script type="text/javascript"><!-- google_ad_client = "pub-2947489232296736"; /* 728x15, 创建于 08-4-23MSDN */ google_ad_slot = "3624277373"; google_ad_width = 728; google_ad_height = 15; //--> </script> <script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> </script>
<script type="text/javascript"><!-- google_ad_client = "pub-2947489232296736"; /* 160x600, 创建于 08-4-23MSDN */ google_ad_slot = "4367022601"; google_ad_width = 160; google_ad_height = 600; //--> </script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> </script>


    数据库中的每个表都是由一个或多个列构成的。在用CREATE TABLE 语句创建一个表时,要为每列指定一个类型。列的类型比数据类型更为特殊,它仅仅是如“数”或“串”这样的通用类型。列的类型精确地描述了给定表列可能包含的值的种类,如SMALLINT 或VARCHAR( 3 2 )。
    MySQL列类型是一种手段,通过这种手段可以描述一个表列包含什么类型的值,这又决定了MySQL怎样处理这些值。例如,数值值既可用数值也可用串的列类型来存放,但是根据存放这些值的类型, MySQL对它们的处理将会有些不同。每种列类型都有父鎏匦匀缦拢?br>     ■ 其中可以存放什么类型的值。
    ■ 值要占据多少空间,以及该值是否是定长的(所有值占相同数量的空间)或可变长的(所占空间量依赖于所存储的值)。
    ■ 该类型的值怎样比较和存储。
    ■ 此类型是否允许NULL 值。
    ■ 此类型是否可以索引。
    我们将简要地考察一下MySQL列类型以获得一个总的概念,然后更详细地讨论描述每种列类型的属性。
    2.2.1列类型概述
    MySQL为除NULL 值以外的所有通用数据类型的值都提供了列类型。在列是否能够包含NULL 值被视为一种类型属性的意义上,可认为所有类型都包含NULL属性。MySQL有整数和浮点数值的列类型,如表2 - 2所示。整数列类型可以有符号也可无符号。有一种特殊的属性允许整数列值自动生成,这对需要唯一序列或标识号的应用系统来说是非常有用的。
11ANMA2Z1IA50.jpg
    MySQL列类型如表2 - 3所示。串可以存放任何内容,即使是像图像或声音这样的绝对二进制数据也可以存放。串在进行比较时可以设定是否区分大小写。此外,可对串进行模式匹配(实际上,在MySQL中可以在任意列类型上进行模式匹配,但最经常进行模式匹配还是在串类型上)
11ANMA9101J2P1.jpg
    日期与时间列类型在表2 - 4中示出。对于临时值, MySQL提供了日期(有或没有时间)、时间和时间戳(一种允许跟踪对记录何时进行最后更改的特殊类型)的类型。而且还提供了一种在不需要完整的日期时有效地表示年份的类型。
11ANMB5401KH29.jpg
   要创建一个表,应使用CREATE TABLE 语句并指定构成表列的列表。每个列都有一个名字和类型,以及与每个类型相关的各种属性。下面是创建具有三个分别名为f、c 和i 的列的表my_table 的例子:
11ANMC1101L9554.jpg
    定义一个列的语法如下:
11ANMC6101MV18.jpg
   其中列名由col_name 给出。列名可最多包含64 个字符,字符包括字母、数字、下划线及美元符号。列名可以名字中合法的任何符号(包括数字)开头。但列名不能完全由数字组成,因为那样可能使其与数据分不开。MySQL保留诸如S E L E C T、DELETE 和CREATE 这样的词,这些词不能用做列名。但是函数名(如POS 和M I N)是可以使用的。
   列类型col_type 表示列可存储的特定值。列类型说明符还能表示存放在列中的值的最大长度。对于某些类型,可用一个数值明确地说明其长度。而另外一些值,其长度由类型名蕴含。例如,CHAR(10) 明确指定了10 个字符的长度。而TINYBLOB 值隐含最大长度为2 5 5个字符。有的类型说明符允许指定最大的显示宽度(即显示值时使用多少个字符)。浮点类型允许指定小数位数,所以能控制浮点数的精度值为多少。
   可以在列类型之后指定可选的类型说明属性,以及指定更多的常见属性。属性起修饰类型的作用,并更改其处理列值的方式,属性有以下类型:
   ■ 专用属性用于指定列。例如,UNSIGNED 属性只针对整型,而B I N A RY 属性只用于CHAR 和VARCHAR。
   ■ 通用属性除少数列之外可用于任意列。可以指定NULL 或NOT NULL 以表示某个列是否能够存放NULL。还可以用D E FA U LT def_value 来表示在创建一个新行但未明确给出该列的值时,该列可赋予值d e f _ v a l ue。def_value 必须为一个常量;它不能是表达式,也不能引用其他列。不能对BLOB 或TEXT 列指定缺省值。
   如果想给出多个列的专用属性,可按任意顺序指定它们,只要它们跟在列类型之后、通用属性之前即可。类似地,如果需要给出多个通用属性,也可按任意顺序给出它们,只要将它们放在列类型和可能给出的列专用属性之后即可。本节其余部分讨论每个MySQL列类型,给出定义类型和描述它们的属性的语法,诸如取值范围和存储需求等。类型说明如在CREATE TABLE 语句中那样给出。可选的信息由方括号([ ])给出。如,语MEDIUMINT[(M)] 表示最大显示宽度(指定为M)是可选的。另一方面,对于CHAR( M ),无方括号表示的(M) 是必须的。
   2.2.2 数值列类型
   MySQL的数值列类型有两种:
   ■ 整型。用于无小数部分的数,如1、4 3、- 3、0 或- 7 9 8 4 3 2。可对正数表示的数据使用整数列,如磅的近似数、英寸的近似数,银河系行星的数目、家族人数或一个盘子里的细菌数等。
   ■ 浮点数。用于可能具有小数部分的数,如3 . 14 15 9、- . 0 0 27 3、- 4 . 7 8、或3 9 . 3 E + 4。可将浮点数列类型用于有小数点部分或极大、极小的数。可能会表示为浮点数的值有农作物平均产量、距离、钱数(如物品价格或工资)、失业率或股票价格等等。整型值也可
以赋予浮点列,这时将它们表示为小数部分为零的浮点值。每种数值类型的名称和取值范围如表2 - 5所示。各种类型值所需的存储量如表2-6 所示。
   CREATE TABLE 语句
   本章中例子中大量使用了CREATE TABLE 语句。您应该对此语句相当熟悉,因为我们在第1章中的教程部分使用过它。关于CREATE TABLE 语句也可参阅附录D。
11ANMCb01NO59.jpg
11ANMD5F1O6012.jpg
    MySQL提供了五种整型: T I N Y I N T、S M A L L I N T、M E D I U M I N T、INT 和B I G I N T。I N T 为I N T E G E R的缩写。这些类型在可表示的取值范围上是不同的。整数列可定义为UNSIGNED 从而禁用负值;这使列的取值范围为0 以上。各种类型的存储量需求也是不同的。
取值范围较大的类型所需的存储量较大。
    MySQL提供三种浮点类型: FLOAT、DOUBLE 和DECIMAL。与整型不同,浮点类型不能是UNSIGNED 的,其取值范围也与整型不同,这种不同不仅在于这些类型有最大值,而且还有最小非零值。最小值提供了相应类型精度的一种度量,这对于记录科学数据来说是非常重要的(当然,也有负的最大和最小值)。
    DOUBLE PRECISION[(M, D)] 和REAL[(M, D)] 为DOUBLE[(M, D)] 的同义词。而NUMERIC(M, D) 为DECIMAL(M, D) 的同义词。FLOAT(4) 和FLOAT(8) 是为了与ODBC 兼容而提供的。在MySQL3.23 以前,它们为FLOAT(10, 2) 和DOUBLE(16, 4) 的同义词。自MySQL3.23 以来,FLOAT(4) 和FLOAT(8) 各不相同,下面还要介绍。
    在选择了某种数值类型时,应该考虑所要表示的值的范围,只需选择能覆盖要取值的范围的最小类型即可。选择较大类型会对空间造成浪费,使表不必要地增大,处理起来没有选择较小类型那样有效。对于整型值,如果数据取值范围较小,如人员年龄或兄弟姐妹数,则TINYINT 最合适。MEDIUMINT 能够表示数百万的值并且可用于更多类型的值,但存储代价较大。BIGINT 在全部整型中取值范围最大,而且需要的存储空间是表示范围次大的整型I N T类型的两倍,因此只在确实需要时才用。对于浮点值, D O U B L E占用FLOAT的两倍空间。除非特别需要高精度或范围极大的值,一般应使用只用一半存储代价的FLOAT型来表示数据。
    在定义整型列时,可以指定可选的显示尺寸M。如果这样,M 应该是一个1到255 的整数。它表示用来显示列中值的字符数。例如, MEDIUMINT(4) 指定了一个具有4 个字符显示宽度的MEDIUMINT 列。如果定义了一个没有明确宽度的整数列,将会自动分配给它一个缺省的宽度。缺省值为每种类型的“最长”值的长度。如果某个特定值的可打印表示需要不止M 个字符,则显示完全的值;不会将值截断以适合M 个字符。对每种浮点类型,可指定一个最大的显示尺寸M 和小数位数D。M 的值应该取1到2 5 5。D 的值可为0 到3 0,但是不应大于M - 2。(如果熟悉ODBC 术语,就会知道M 和D 对应于
ODBC 概念的“精度”和“小数点位数”)M 和D 对FLOAT和DOUBLE 都是可选的,但对于DECIMAL 是必须的。在选项M 和D时,如果省略了它们,则使用缺省值。下面的语句创建了一个表,它说明了数值列类型的M 和D 的缺省值(其中不包括DECIMAL,因为M 和D 对这种类型不是可选的):
11ANME2P1P4D0.jpg
    如果在创建表之后使用DESCRIBE my_table 语句,则输出的Field 和Type 列如下所示(注意,如果用MySQL的3.23 以前的版本运行这个查询,则有一个小故障, 即BIGINT 的显示宽度将是21而不是2 0。):
11ANMEO01Q3062.jpg
    每一个数字列都具有一个由列类型所决定的取值范围。如果打算插入一个不在列范围内的值,将会进行截取:MySQL将剪裁该值为取值范围的边界值并使用这个结果。在检索时不进行值的剪裁。
    值的剪裁根据列类型的范围而不是显示宽度进行。例如,一个SMALLINT(3) 列显示宽度为3 而取值范围为-32768 到3 27 6 7。值12345 比显示宽度大,但在该列的取值范围内,因此它可以插入而不用剪裁并且作为12345 检索。值99999 超出了取值范围,因此在插入时被剪裁为3 27 6 7。以后在检索中将以值3 27 6 7检索该值。
    一般赋予浮点列的值被四舍五入到这个列所指定的十进制数。如果在一个FLOAT(8, 1)的列中存储1. 2 3 4 5 6,则结果为1. 2。如果将相同的值存入FLOAT(8, 4) 的列中,则结果为1. 2 3 4 6。这表示应该定义具有足够位数的浮点列以便得到尽可能精确的值。如果想精确到千分之一,那就不要定义使该类型仅有两位小数。
    浮点值的这种处理在MySQL3.23 中有例外,FLOAT(4) 和FLOAT(8) 的性能有所变化。这两种类型现在为单精度( 4 字节)和双精度( 8 字节)的类型,在其值按给出的形式存放(只受硬件的限制)这一点上说,这两种类型是真浮点类型。
    DECIMAL 类型不同于FLOAT和DECIMAL,其中DECIMAL 实际是以串存放的。DECIMAL 可能的最大取值范围与DOUBLE 一样,但是其有效的取值范围由M 和D 的值决定。如果改变M 而固定D,则其取值范围将随M 的变大而变大。表2 - 7的前三行说明了这一点。如果固定M 而改变D,则其取值范围将随D 的变大而变小(但精度增加)。表2 - 7的后三行说明了这一点。
11ANMF301R1091.jpg
    给定的DECIMAL 类型的取值范围取决于MySQL的版本。对于MySQL3.23 以前的版本,DECIMAL(M, D) 列的每个值占用M 字节,而符号(如果需要)和小数点包括在M 字节中。因此,类型为DECIMAL(5, 2) 的列,其取值范围为-9.99 到9 9 . 9 9,因为它们覆盖了所有可能的5 个字符的值。
    正如MySQL3.23 一样,DECIMAL 值是根据ANSI 规范进行处理的, ANSI 规范规定DECIMAL(M, D) 必须能够表示M 位数字及D 位小数的任何值。例如, DECIMAL(5, 2) 必须能够表示从-999.99 到999.99 的所有值。而且必须存储符号和小数点,因此自MySQL3.23以来DECIMAL 值占M + 2 个字节。对于DECIMAL(5, 2),“最长”的值(- 9 9 9 . 9 9)需要7个字节。在正取值范围的一端,不需要正号,因此MySQL利用它扩充了取值范围,使其超
过了ANSI 所规范所要求的取值范围。如DECIMAL(5, 2) 的最大值为9 9 9 9 . 9 9,因为有7 个字节可用。
    简而言之,在MySQL3.23 及以后的版本中,DECIMAL(M, D) 的取值范围等于更早版本中的DECIMAL(M + 2, D) 的取值范围。在MySQL的所有版本中,如果某个DECIMAL 列的D 为0,则不存储小数点。这样做的结果是扩充了列的取值范围,因为过去用来存储小数点的字节现在可用来存放其他数字了。
    1. 数值列的类型属性
    可对所有数值类型指定ZEROFILL 属性。它使相应列的显示值用前导零来填充,以达到显示宽度。在希望确定列值总是以给定的数字位数显示时可利用Z E R O F I L L。实际上,更准确地说是“一个给定的最小数目的数字位数”,因为比显示宽度更宽的值可完全显示而未被剪裁。使用下列语句可看到这一点:
11ANMFJ01SB63.jpg
    其中SELECT 语句的输出结果如下。请注意最后一行值,它比列的显示宽度更宽,但仍然完全显示出来:
11ANMG1601T2201.jpg
    如下所示两个属性只用于整数列:
    ■ AUTO_INCREMENT。在需要产生唯一标识符或顺序值时,可利用AUTO_ INCREMENT属性。AUTO_INCREMENT 值一般从1开始,每行增加1。在插入NULL 到一个AUTO _INCREMENT 列时,MySQL插入一个比该列中当前最大值大1的值。一个表中最多只能有一个AUTO_INCREMENT 列。对于任何想要使用AUTO_INCREMENT 的列,应该定义为NOT NULL,并定义为PRIMARY KEY 或定义为UNIQUE 键。例如, 可按下列任何一种方式定义AUTO_INCREMENT 列:
11ANMGG01U4238.jpg
    AUTO_INCREMENT 的性能将在下一小节“使用序列”中作进一步的介绍。
    ■ U N S I G N E D。此属性禁用负值。将列定义为UNSIGNED 并不改变其基本数据类型的取值范围;它只是前移了取值的范围。考虑下列的表说明:
11ANMH1F1V1194.jpg
    itiny 和itiny_u两列都是T I N Y I N T列,并且都可取2 5 6个值,但是i t i n y的取值范围为-12 8 到127,而itiny_u的取值范围为0 到2 5 5。UNSIGNED 对不取负值的列是非常有用的,如存入人口统计或出席人数的列。如果用常规的有符号列来存储这样的值,那么就只利用了该列类型取值范围的一半。通过使列为U N S I G N E D,能有效地成倍增加其取值范围。如果将列用于序列号,且将它设为U N S I G N E D,则可取原双倍的值。在指定以上属性之后(它们是专门用于数值列的),可以指定通用属性NULL 或N O TNULL。如果未指定NULL 或NOT NULL,则缺省为NULL。也可以用D E FA U LT 属性来指定一个缺省值。如果不指定缺省值,则会自动选择一个。对于所有数值列类型,那些可以包含NULL 的列的缺省将为NULL,不能包含NULL 的列其缺省为0。下面的样例创建三个INT 列,它们分别具有缺省值-1、1和NULL:
11ANMHF1W2140.jpg
    2. 使用序列
    许多应用程序出于标识的目的需要使用唯一的号码。需要唯一值的这种要求在许多场合都会出现,如:会员号、试验样品编号、顾客ID、错误报告或故障标签等等。AUTO_INCREMENT 列可提供唯一编号。这些列可自动生成顺序编号。本节描述AUTO_INCREMENT 列是怎样起作用的,从而使您能够有效地利用它们而不至于出错。另外,还介绍了怎样不用AUTO_INCREMENT 列来产生序列的方法。
    (1) MySQL3.23 以前的版本中的AUTO _ I N C R E M E N TMySQL3.23 版以前的AUTO_INCREMENT 列的性能如下:
    ■ 插入NULL 到AUTO_INCREMENT 列,使MySQL自动地产生下一个序列号并将此序列号自动地插入列中。AUTO_INCREMENT 序列从1开始,因此插入表中的第一个记录得到为1的序列值,而后继插入的记录分别得到序列值2、3 等等。一般,每个自动生成的值都比存储在该列中的当前最大值大1。
    ■ 插入0 到AUTO_INCREMENT 与插入NULL 到列中的效果一样。插入一行而不指定AUTO_INCREMENT 列的值也与插入NULL 的效果一样。
    ■ 如果插入一个记录并明确指定AUTO_INCREMENT 列的一个值,将会发生两件事之一。如果已经存在具有该值的某个记录,则出错,因为AUTO_INCREMENT 列中的值必须是惟一的。如果不存在具有该值的记录,那么新记录将被插入,并且如果新记录的AUTO_INCREMENT 列中的值是新的最大值,那么后续行将用该值的下一个值。换句话说,也就是可以通过插入一个具有比当前值大的序列值的记录,来增大序列的计数器。增大计数器会使序列出现空白,但这个特性也有用。例如创建一个具有AUTO _INCREMENT 列的表,但希望序列从1000 而不是1开始。则可以用后述的两种办法之一达到此目的。一个办法是插入具有明确序列值1000 的第一个记录,然后通过插入NULL 到AUTO_INCREMENT 列来插入后续的记录。另一个办法是插入
AUTO_INCREMENT 列值为999 的假记录。然后第一个实际插入的记录将得到一个序列号10 0 0,这时再将假记录删除。
    ■ 如果将一个不合规定的值插入AUTO_INCREMENT 列,将会出现难以预料的结果。
    ■ 如果删除了在AUTO_INCREMENT 列中含有最大值的记录,则此值在下一次产生新值时会再次使用。如果删除了表中的所有记录,则所有值都可以重用;相应的序列重新从1开始。
    ■ REPLACE 语句正常起作用。
    ■ UPDATE语句按类似插入新记录的规则起作用。如果更新一个AUTO _ I N C R E M E N T列为NULL 或0,则会自动将其更新为下一个序列号。如果试图更新该列为一个已经存在的值,将出错(除非碰巧设置此列的值为它所具有的值,才不会出错,但这没有任何意义)。如果更新该列的值为一个比当前任何列值都大的值,则以后序列将从下一个值继续进行编号。
    ■ 最近自动产生的序列编号值可调用L A S T _ INSERT_ID( ) 函数得到。它使得能在其他不知道此值的语句中引用AUTO_INCREMENT 值。L A S T _ INSERT_ID( ) 依赖于当前服务器会话中生成的AUTO_INCREMENT 值; 它不受与其他客户机相关的AUTO_INCREMENT 活动的影响。如果当前会话中没有生成AUTO_INCREMENT 值,则L A S T _ INSERT_ID( ) 返回0。能够自动生成顺序编号这个功能特别有用。但是刚才介绍的AUTO_INCREMENT 性能有两个缺陷。首先,序列中顶上的记录被删除时,序列值的重用使得难于生成可能删除和插入记录的应用的一系列单调(严格递增)值。其次,利用从大于1的值开始生成序列的方法是很笨的。
    (2) MySQL3.23 版以后的AUTO_INCREMENTMySQL3.23 对AUTO_INCREMENT 的性能进行了下列变动以便能够处理上述问题:
    ■ 自动顺序生成的值严格递增且不重用。如果最大的值为143 并删除了包含这个值的记录,MySQL继续生成下一个值14 4。
    ■ 在创建表时,可以明确指定初始的序列编号。下面的例子创建一个AUTO _ I N C R E -MENT 列seq 从1,000,000 开始的表:
11ANMI1201X5522.jpg
    在一个表具有多个列时(正如多数表那样),最后的AUTO_INCREMENT = 1000000子句应用到哪一列是不会混淆的,因为每个表只能有一个AUTO_INCREMENT 列。
    (3) 使用AUTO_INCREMENT 应该考虑的问题在使用AUTO_INCREMENT 列时,应该记住下列要点:
    ■ AUTO_INCREMENT 不是一种列类型,它只是一种列类型属性。此外, AUTO _INCREMENT 是一种只能用于整数类型的属性。MySQL早于3.23 的版本并不严格服从这个约束,允许定义诸如CHAR 这样的列类型具有AUTO_INCREMENT 属性。但是只有整数类型作为AUTO_INCREMENT 列正常起作用。
    ■ AUTO_INCREMENT 机制的主要目的是生成一个正整数序列,并且如果以这种方式使用,则AUTO_INCREMENT 列效果最好。所以应该定义AUTO_INCREMENT 列为U N S I G N E D。这样做的优点是在到达列类型的取值范围上限前可以进行两倍的序列编号。在某些环境下,也有可能利用AUTO_INCREMENT 列来生成负值的序列,但是我们不建议这样做。如果您决定要试一下,应该保证进行充分的试验,并且在升级到不同的MySQL版本时需要重新测试。笔者的经验表明,不同的版本中,负序列的性能并不完全一致。
    ■ 不要认为对某个列定义增加AUTO_INCREMENT 是一个得到无限的编号序列的奇妙方法。事实并非这样; AUTO_INCREMENT 序列受基础列类型的取值范围所限制。例如,如果使用TINYINT UNSIGNED 列,则最大的序列号为2 5 5。在达到这个界限时,应用程序将开始出现“重复键”错误。
    ■ MySQL3.23 引入了不重用序列编号的新AUTO_INCREMENT 性能,并且允许在CREATE TABLE 语句中指定一个初始的序列编号。这些性能在使用下列形式的DELETE 语句删除了表中所有记录后可以撤消:
11ANMI5401Y4310.jpg
    在此情形下,序列重新从1开始而不按严格的增量顺序继续增加。即使在C R E AT ETABLE 语句中明确指定了一个初始的序列编号,相应的序列也会从头开始。出现这种情形的原因在于MySQL优化完全删空一个表的DELETE 语句的方法上;它从头开始重新创建数据文件和索引文件而不是去删除每个记录,这样就丢失了所有的序列号信息。如果要删除所有记录,但希望保留序列信息,可以取消优化并强制MySQL执行逐行的删除操作,如下所示:
11ANMIX01ZGJ.jpg
    如果使用的是3 . 2 3以上的版本,怎样保持严格的增量序列?方法之一是保持一个只用来生成AUTO_INCREMENT 值的独立的表,永远不从这个表中删除记录。在这种情况下,独立表中的值永远不会重用。在主表中需要生成一个新记录时,首先在序列编号表中插入一个NULL。然后对希望包含序列编号的列使用L A S T _ INSERT_ID( ) 的值将该记录插入主表,如下所示:
11ANMJ4401916131.jpg
    如果想要编写一个生成AUTO_INCREMENT 值的应用程序,但希望序列从100 而不是1开始。再假定希望这个程序可移植到所有MySQL版本。怎样来完成它呢?如果可移植是一个目标,那么不能依赖MySQL3.23 所提供的在CREATE TABLE 语句中指定初始序列编号的功能。而是在想要插入一个记录时,首先用下列语句检查表是否是空的:
11ANMJQ01921244.jpg
    这个步骤虽然是附加的,但不会花费太多的时间,因为没有WHERE 子句的SELECT COUNT(*) 是优化的,返回很快。如果表是空的,则插入记录并明确地对序列编号列指定值10 0。如果表不空,则对序列编号列值指定NULL 使MySQL自动生成下一个编号。此方法允许插入序列编号为10 0、101等的记录,它不管MySQL是否允许指定初始序列值都能正常工作。如果要求序列编号即使是从表中删除了记录后也要严格递增,则此方法不起作用。在这样的情形下,可将此方法与前面描述的什么也不做只是用来产生用于主表的序列编号的辅助表技术结合使用。为什么会希望从一个大于1的序列编号开始呢?一个原因是想使所有序列编号全都具有相同的数字位数。如果需要生成顾客ID 号,并且希望不要多于一百万个顾客,则可以从1000 000
开始编号。在对顾客ID 值计数的数字位数改变之前,可以追加一百万个顾客。当然,强制序列编号为一个固定宽度的另一个方法是采用ZEROFILL 列。对于有的情形,这样做有可能会出问题。例如,如果在Perl 或PHP 脚本中处理具有前导零的序列编号,则必须仔细地将它们只作为串使用;如果将它们转换成数字,前导零将会丢失。下面的短Perl 脚本说明了处理编号时可能会出的问题:
11ANMK210193C42.jpg
    打印时,此脚本给出下列输出:
11ANMKE01943017.jpg
    Perl’s‘+ +’自动增量操作是很灵巧的而且可以利用串或数值建立序列值,但‘+ =’操作只应用于数值。在所显示的输出中,可看到‘ + =’引起串到数值的转换并且丢失了$s 值中的前导零。
    序列不从1开始的另一个原因从技术的角度来说可能不值一提。例如,在分配会员号时,序列号不要从1开始,以免出现关于谁是第一号的政治争论。
    (4) 不用AUTO_INCREMENT 生成序列生成序列号的另一个方法根本就不需要使用AUTO_INCREMENT 列。它利用取一个参数的L A S T _ INSERT_ID( ) 函数的变量来生成序列号。(这种形式在MySQL3.22.9. 中引入)如果利用L A S T _ INSERT_ID(expr) 来插入或更新一个列, 则下一次不用参数调用L A S T _ INSERT_ID( ) 时,将返回expr 的值。换句话说,就像由AUTO_INCREMENT 机制生成的那样对expr 进行处理。这样使得能生成一个序列号,然后可在以后的客户会话中利用它,用不着取受其他客户机影响的值。利用这种策略的一种方法是创建一个包含一个值的单行表,该值在想得到序列中下一个值时进行更新。例如,可创建如下的表: 共3页: 上一页 1 [2] [3] 下一页 <script type="text/javascript"><!-- google_ad_client = "pub-2947489232296736"; /* 728x15, 创建于 08-4-23MSDN */ google_ad_slot = "3624277373"; google_ad_width = 728; google_ad_height = 15; //--> </script> <script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> </script>

<script type="text/javascript"><!-- google_ad_client = "pub-2947489232296736"; /* 160x600, 创建于 08-4-23MSDN */ google_ad_slot = "4367022601"; google_ad_width = 160; google_ad_height = 600; //--> </script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> </script>
阅读更多
个人分类: 数据库
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

不良信息举报

MySQL的列类型

最多只允许输入30个字

加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!
关闭
关闭