当前位置:七道奇文章资讯数据防范MySQL防范
日期:2011-05-02 15:44:00  来源:本站整理

MySQL数据库技术(08)[MySQL防范]

赞助商链接



  本文“MySQL数据库技术(08)[MySQL防范]”是由七道奇为您精心收集,来源于网络转载,文章版权归文章作者所有,本站不对其观点以及内容做任何评价,请读者自行判断,以下是其具体内容:

? 数据库中的每个表都是由一个或多个列构成的.在用C R E ATE TABLE 语句成立一个表时,要为每列指定一个范例.列的范例比数据范例更为特别,它仅仅是如"数"或"串"这样的通用范例.列的范例切确地描写了给定表列大概包含的值的种类,如SMALLINT 或VA R C H A R ( 3 2 ).
? ? MySQL 的列范例是一种手段,通过这种手段可以描写一个表列包含什么范例的值,这又决意了MySQL 怎样处理这些值.比方,数值值既可用数值也可用串的列范例来存放,但是按照存放这些值的范例, MySQL 对它们的处理将会有些差别.每种列范例都有几个特点以下:
? ? ■ 此中可以存放什么范例的值.
? ? ■ 值要占据多少空间,以及该值能否是定长的(全部值占相同数目的空间)或可变长的(所占空间量依靠于所存储的值).
? ? ■ 该范例的值怎样对比和存储.
? ? ■ 此范例能否答应NULL 值.
? ? ■ 此范例能否可以索引.
? ? 我们将扼要地观察一下M y S Q L列范例以得到一个总的概念,然后更具体地谈论描写每种列范例的属性.
? ? 2.2.1 列范例概述
? ? MySQL 为除NULL 值以外的全部通用数据范例的值都供应了列范例.在列能否可以包含NULL 值被视为一种范例属性的意义上,可认为全部范例都包含N U L L属性.M y S Q L有整数和浮点数值的列范例,如表2 - 2所示.整数列范例可以有标记也可无标记.有一种特别的属性答应整数列值自动生成,这对需求唯一序列或标识号的利用系统来说是非常有效的.
MySQL数据库技术(08)
? ? MySQL 串列范比方表2 - 3所示.串可以存放任何内容,即便是像图象或声音这样的绝对二进制数据也可以存放.串在举行对比时可以设定能否辨别大小写.此外,可对串举行情势匹配(实际上,在MySQL 中可以在肆意列范例上举行情势匹配,但最常常举行情势匹配还是在串范例上)
MySQL数据库技术(08)
? ??日期与时间列范例在表2 - 4中示出.关于暂时值, MySQL 供应了日期(有或没有时间)、时间和时间戳(一种答应跟踪对记录什么时刻举行最后更改的特别范例)的范例.并且还供应了一种在不需求完好的日期时有效地表示年份的范例.
MySQL数据库技术(08)
? ?要成立一个表,应利用C R E ATE TABLE 语句并指定构成表列的列表.每个列都有一个名字和范例,以及与每个范例相关的各种属性.下面是成立具有三个辨别名为f、c 和i 的列的表my_table 的例子:
MySQL数据库技术(08)
? ? 定义一个列的语法以下:
MySQL数据库技术(08)
? ?此中列名由col_name 给出.列名可最多包含64 个字符,字符包含字母、数字、下划线及美圆标记.列名可以名字中合理的任何标记(包含数字)开首.但列名不能完好由数字构成,因为那样大概使其与数据分不开.M y S Q L保存诸如S E L E C T、DELETE 和C R E ATE 这样的词,这些词不能用做列名.但是函数名(如POS 和M I N)是可以利用的.
? ?列范例col_type 表示列可存储的特定值.列范例阐明符还能表示存放在列中的值的最大长度.关于某些范例,可用一个数值明确地阐明其长度.而别的一些值,其长度由范例名包含.比方,CHAR(10) 明确指定了10 个字符的长度.而TINYBLOB 值隐含最大长度为2 5 5个字符.有的范例阐明符答应指定最大的显示宽度(即显示值时利用多少个字符).浮点范例答应指定小数位数,所以能掌握浮点数的精度值为多少.
? ?可以在列范例之后指定可选的范例阐明属性,以及指定更多的常见属性.属性起修饰范例的作用,并更改其处理列值的方法,属性有以下范例:
? ?■ 专用属性用于指定列.比方,UNSIGNED 属性只针对整型,而B I N A RY 属性只用于CHAR 和VA R C H A R.
? ?■ 通用属性除少数列之外可用于肆意列.可以指定NULL 或NOT NULL 以表示某个列能否可以存放N U L L.还可以用D E FA U LT def_value 来表示在成立一个新行但未明确给出该列的值时,该列可赋予值d e f _ v a l u e.def_value 必须为一个常量;它不能是表达式,也不能引用其他列.不能对BLOB 或TEXT 列指定缺省值.
? ?假如想给出多个列的专用属性,可按肆意次序指定它们,只要它们跟在列范例之后、通用属性之前便可.近似地,假如需求给出多个通用属性,也可按肆意次序给出它们,只要将它们放在列范例和大概给出的列专用属性之后便可.本节别的部份谈论每个MySQL 的列范例,给出定义范例和描写它们的属性的语法,诸如取值范围和存储需求等.范例阐明如在C R E ATE TABLE 语句中那样给出.可选的信息由方括号([ ])给出.如,语MEDIUMINT[(M)] 表示最大显示宽度(指定为M)是可选的.另一方面,关于C H A R ( M ),无方括号表示的(M) 是必须的.
? ?2.2.2 数值列范例
? ?MySQL 的数值列范例有两种:
? ?■ 整型.用于无小数部份的数,如1、4 3、- 3、0 或- 7 9 8 4 3 2.可对正数表示的数据利用整数列,如磅的近似数、英寸的近似数,银河系行星的数目、家族人数或一个盘子里的细菌数等.
? ?■ 浮点数.用于大概具有小数部份的数,如3 . 1 4 1 5 9、- . 0 0 2 7 3、- 4 . 7 8、或3 9 . 3 E + 4.可将浮点数列范例用于有小数点部份或极大、极小的数.大概会表示为浮点数的值有农作物平均产量、距离、钱数(如物品价钱或工资)、失业率或股票价钱等等.整型值也可
以赋予浮点列,这时将它们表示为小数部份为零的浮点值.每种数值范例的名称和取值范围如表2 - 5所示.各种范例值所需的存储量如表2-6 所示.
? ?CREATE TABLE 语句
? ?本章中例子中大量利用了C R E ATE TABLE 语句.您应当对此语句相当熟习,因为我们在第1章中的教程部份利用过它.关于C R E ATE TABLE 语句也可参阅附录D.
MySQL数据库技术(08)
MySQL数据库技术(08)
? ? 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 供应三种浮点范例: F L O AT、DOUBLE 和D E C I M A L.与整型差别,浮点范例不能是UNSIGNED 的,其取值范围也与整型差别,这种差别不但在于这些范例有最大值,并且还有最小非零值.最小值供应了呼应范例精度的一种器量,这关于记录科学数据来说是非常重要的(当然,也有负的最大和最小值).
? ? DOUBLE PRECISION[(M, D)] 和REAL[(M, D)] 为DOUBLE[(M, D)] 的同义词.而NUMERIC(M, D) 为DECIMAL(M, D) 的同义词.F L O AT(4) 和F L O AT(8) 是为了与ODBC 兼容而供应的.在MySQL 3.23 从前,它们为F L O AT(10, 2) 和DOUBLE(16, 4) 的同义词.自MySQL 3.23 以来,F L O AT(4) 和F L O AT(8) 各不相同,下面还要介绍.
? ? 在挑选了某种数值范例时,应当考虑所要表示的值的范围,只需挑选能覆盖要取值的范围的最小范例便可.挑选较大范例会对空间造成浪费,使表不必要地增大,处理起来没有挑选较小范例那样有效.关于整型值,假如数据取值范围较小,如人员年纪或兄弟姐妹数,则TINYINT 最符合.MEDIUMINT 可以表示数百万的值并且可用于更多范例的值,但存储代价较大.BIGINT 在全部整型中取值范围最大,并且需求的存储空间是表示范围次大的整型I N T范例的两倍,因此只在确切需求时才用.关于浮点值, D O U B L E占用F L O AT 的两倍空间.除非分外需求高精度或范围极大的值,普通应利用只用一半存储代价的F L O AT 型来表示数据.
? ? 在定义整型列时,可以指定可选的显示尺寸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 对F L O AT 和DOUBLE 都是可选的,但关于DECIMAL 是必须的.在选项M 和D时,假如省略了它们,则利用缺省值.下面的语句成立了一个表,它阐明了数值列范例的M 和D 的缺省值(此中不包含D E C I M A L,因为M 和D 对这种范例不是可选的):
MySQL数据库技术(08)
? ? 假如在成立表之后利用DESCRIBE my_table 语句,则输出的Field 和Type 列以下所示(注意,假如用MySQL 的3.23 从前的版本运行这个查询,则有一个小弊端, 即BIGINT 的显示宽度将是21 而不是2 0.):
MySQL数据库技术(08)
? ? 每一个数字列都具有一个由列范例所决意的取值范围.假如打算插入一个不在列范围内的值,将会举行截取:MySQL 将剪裁该值为取值范围的边界值并利用这个后果.在检索时不举行值的剪裁.
? ? 值的剪裁按照列范例的范围而不是显示宽度举行.比方,一个SMALLINT(3) 列显示宽度为3 而取值范围为-32768 到3 2 7 6 7.值12345 比显示宽度大,但在该列的取值范围内,因此它可以插入而不用剪裁并且作为12345 检索.值99999 超越了取值范围,因此在插入时被剪裁为3 2 7 6 7.今后在检索中将以值3 2 7 6 7检索该值.
? ? 普通赋予浮点列的值被四舍五入到这个列所指定的十进制数.假如在一个F L O AT(8, 1)的列中存储1 . 2 3 4 5 6,则后果为1 . 2.假如将相同的值存入F L O AT(8, 4) 的列中,则后果为1 . 2 3 4 6.这表示应当定义具有充足位数的浮点列以便得到尽大概切确的值.假如想切确到千分之一,那就不要定义使该范例唯一两位小数.
? ? 浮点值的这种处理在MySQL 3.23 中有例外,F L O AT(4) 和F L O AT(8) 的性能有所改变.这两种范例目前为单精度( 4 字节)和双精度( 8 字节)的范例,在其值按给出的情势存放(只受硬件的限制)这一点上说,这两种范例是真浮点范例.
? ? DECIMAL 范例差别于F L O AT 和D E C I M A L,此中DECIMAL 实际是以串存放的.DECIMAL 大概的最大取值范围与DOUBLE 一样,但是其有效的取值范围由M 和D 的值决意.假如改变M 而固定D,则其取值范围将随M 的变大而变大.表2 - 7的前三行阐明了这一点.假如固定M 而改变D,则其取值范围将随D 的变大而变小(但精度增添).表2 - 7的后三行阐明了这一点.
MySQL数据库技术(08)
? ? 给定的DECIMAL 范例的取值范围取决于MySQL 的版本.关于MySQL 3.23 从前的版本,DECIMAL(M, D) 列的每个值占用M 字节,而标记(假如需求)和小数点包含在M 字节中.因此,范例为DECIMAL(5, 2) 的列,其取值范围为-9.99 到9 9 . 9 9,因为它们覆盖了全部大概的5 个字符的值.
? ? 正如MySQL 3.23 一样,DECIMAL 值是按照ANSI 标准举行处理的, ANSI 标准规定DECIMAL(M, D) 必须可以表示M 位数字及D 位小数的任何值.比方, DECIMAL(5, 2) 必须可以表示从-999.99 到999.99 的全部值.并且必须存储标记和小数点,因此自MySQL 3.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 个字节可用.
? ? 简而言之,在MySQL 3.23 及今后的版本中,DECIMAL(M, D) 的取值范围等于更早版本中的DECIMAL(M + 2, D) 的取值范围.在MySQL 的全部版本中,假如某个DECIMAL 列的D 为0,则不存储小数点.这样做的后果是扩大了列的取值范围,因为过去用来存储小数点的字节目前可用来存放其他数字了.
? ? 1. 数值列的范例属性
? ? 可对全部数值范例指定ZEROFILL 属性.它使呼应列的显示值用前导零来填充,以到达显示宽度.在但愿肯定列值老是以给定的数字位数显示时可操纵Z E R O F I L L.实际上,更精确地说是"一个给定的最小数目的数字位数",因为比显示宽度更宽的值可完好显示而未被剪裁.利用下列语句可看到这一点:
MySQL数据库技术(08)
? ? 此中SELECT 语句的输出后果以下.请注意最后一行值,它比列的显示宽度更宽,但仍旧完好显示出来:
MySQL数据库技术(08)
? ? 以下所示两个属性只用于整数列:
? ? ■ AUTO_INCREMENT.在需求产生唯一标识符或次序值时,可操纵AUTO_ INCREMENT属性.A U TO_INCREMENT 值普通从1开始,每行增添1.在插入NULL 到一个A U TO _INCREMENT 列时,MySQL 插入一个比该列中当前最大值大1 的值.一个表中最多只能有一个A U TO_INCREMENT 列.关于任何想要利用A U TO_INCREMENT 的列,应当定义为NOT NULL,并定义为P R I M A RY KEY 或定义为UNIQUE 键.比方, 可按下列任何一种方法定义AUTO_INCREMENT 列:
MySQL数据库技术(08)
? ? A U TO_INCREMENT 的性能将在下一小节"利用序列"中作进一步的介绍.
? ? ■ U N S I G N E D.此属性禁用负值.将列定义为UNSIGNED 并不改变其基本数据范例的取值范围;它只是前移了取值的范围.考虑下列的表阐明:
MySQL数据库技术(08)
? ? itiny 和itiny_u 两列都是T I N Y I N T列,并且都可取2 5 6个值,但是i t i n y的取值范围为-1 2 8 到1 2 7,而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 TN U L L.假如未指定NULL 或NOT NULL,则缺省为N U L L.也可以用D E FA U LT 属性来指定一个缺省值.假如不指定缺省值,则会自动挑选一个.关于全部数值列范例,那些可以包含NULL 的列的缺省将为N U L L,不能包含NULL 的列其缺省为0.下面的样例成立三个INT 列,它们辨别具有缺省值-1、1 和N U L L:
MySQL数据库技术(08)
? ? 2. 利用序列
? ? 很多利用程序出于标识的目的需求利用唯一的号码.需求唯一值的这种要求在很多场所城市呈现,如:会员号、试验样品编号、顾客I D、错误报告或弊端标签等等.A U TO_INCREMENT 列可供应唯一编号.这些列可自动生成次序编号.本节描写A U TO_INCREMENT 列是怎样起作用的,从而使您可以有效地操纵它们而不至于出错.别的,还介绍了怎样不用A U TO_INCREMENT 列来产生序列的办法.
? ? (1) MySQL 3.23 从前的版本中的A U TO _ I N C R E M E N TMySQL 3.23 版从前的A U TO_INCREMENT 列的性能以下:
? ? ■ 插入NULL 到A U TO_INCREMENT 列,使MySQL 自动地产生下一个序列号并将此序列号自动地插入列中.A U TO_INCREMENT 序列从1 开始,因此插入表中的第一个记录得到为1 的序列值,此后继插入的记录辨别得到序列值2、3 等等.普通,每个自动生成的值都比存储在该列中的当前最大值大1.
? ? ■ 插入0 到A U TO_INCREMENT 与插入NULL 到列中的效果一样.插入一行而不指定A U TO_INCREMENT 列的值也与插入NULL 的效果一样.
? ? ■ 假如插入一个记录并明确指定A U TO_INCREMENT 列的一个值,将会发生两件事之一.假如已经存在具有该值的某个记录,则出错,因为A U TO_INCREMENT 列中的值必须是惟一的.假如不存在具有该值的记录,那么新记录将被插入,并且假如新记录的A U TO_INCREMENT 列中的值是新的最大值,那么后续行将用该值的下一个值.换句话说,也就是可以通过插入一个具有比当前值大的序列值的记录,来增大序列的计数器.增大计数器会使序列呈现空白,但这个特点也有效.比方成立一个具有A U TO _INCREMENT 列的表,但但愿序列从1000 而不是1 开始.则可以用后述的两种办法之一到达此目的.一个办法是插入具有明确序列值1000 的第一个记录,然后通过插入NULL 到A U TO_INCREMENT 列来插入后续的记录.另一个办法是插入
A U TO_INCREMENT 列值为999 的假记录.然后第一个实际插入的记录将得到一个序列号1 0 0 0,这时再将假记录删除.
? ? ■ 假如将一个不合规定的值插入A U TO_INCREMENT 列,将会呈现难以意料的后果.
? ? ■ 假如删除了在A U TO_INCREMENT 列中含有最大值的记录,则此值在下一次产生新值时会再次利用.假如删除了表中的全部记录,则全部值都可以重用;呼应的序列重新从1开始.
? ? ■ REPLACE 语句正常起作用.
? ? ■ U P D ATE 语句按近似插入新记录的法则起作用.假如更新一个A U TO _ I N C R E M E N T列为NULL 或0,则会自动将其更新为下一个序列号.假如试图更新该列为一个已经存在的值,将出错(除非刚巧设置此列的值为它所具有的值,才不会出错,但这没有任何意义).假如更新该列的值为一个比当前任何列值都大的值,则今后序列将从下一个值持续举行编号.
? ? ■ 近来自动产生的序列编号值可调用L A S T _ I N S E RT_ID( ) 函数得到.它使得能在其他不知道此值的语句中引用A U TO_INCREMENT 值.L A S T _ I N S E RT_ID( ) 依靠于当前服务器会话中生成的A U TO_INCREMENT 值; 它不受与其他客户机相关的A U TO_INCREMENT 活动的影响.假如当前会话中没有生成A U TO_INCREMENT 值,则L A S T _ I N S E RT_ID( ) 返回0.可以自动生成次序编号这个功效分外有效.但是方才介绍的A U TO_INCREMENT 性能有两个缺陷.首先,序列中顶上的记录被删除时,序列值的重用使得难于生成大概删除和插入记录的利用的一系列单调(严峻递增)值.其次,操纵从大于1的值开始生成序列的办法是很笨的.
? ? (2) MySQL 3.23 版今后的A U TO_INCREMENTMySQL 3.23 对A U TO_INCREMENT 的性能举行了下列变更以便可以处理上述问题:
? ? ■ 自动次序生成的值严峻递增且不重用.假如最大的值为143 并删除了包含这个值的记录,MySQL 持续生成下一个值1 4 4.
? ? ■ 在成立表时,可以明确指定初始的序列编号.下面的例子成立一个A U TO _ I N C R E -MENT 列seq 从1,000,000 开始的表:
MySQL数据库技术(08)
? ? 在一个表具有多个列时(正如大都表那样),最后的A U TO_INCREMENT = 1000000子句利用到哪一列是不会混合的,因为每个表只能有一个A U TO_INCREMENT 列.
? ? (3) 利用A U TO_INCREMENT 应当考虑的问题在利用A U TO_INCREMENT 列时,应当记着下列要点:
? ? ■ A U TO_INCREMENT 不是一种列范例,它只是一种列范例属性.此外, A U TO _INCREMENT 是一种只能用于整数范例的属性.MySQL 早于3.23 的版本并不严峻固守这个约束,答应定义诸如CHAR 这样的列范例具有A U TO_INCREMENT 属性.但是只有整数范例作为A U TO_INCREMENT 列正常起作用.
? ? ■ A U TO_INCREMENT 机制的主要目的是生成一个正整数序列,并且假如以这种方法利用,则A U TO_INCREMENT 列效果最好.所以应当定义A U TO_INCREMENT 列为U N S I G N E D.这样做的长处是在到达列范例的取值范围上限前可以举行两倍的序列编号.在某些环境下,也有大概操纵A U TO_INCREMENT 列来生成负值的序列,但是我们不倡议这样做.假如您决意要试一下,应当保证举行充分的试验,并且在进级到差别的MySQL 版本时需求重新测试.笔者的经验表明,差别的版本中,负序列的性能并不完好一致.
? ? ■ 不要认为对某个列定义增添A U TO_INCREMENT 是一个得到无限的编号序列的奥妙办法.事实并非这样; A U TO_INCREMENT 序列受底子列范例的取值范围所限制.比方,假如利用TINYINT UNSIGNED 列,则最大的序列号为2 5 5.在到达这个边界时,利用程序将开始呈现"反复键"错误.
? ? ■ MySQL 3.23 引入了不重用序列编号的新A U TO_INCREMENT 性能,并且答应在C R E ATE TABLE 语句中指定一个初始的序列编号.这些性能在利用下列情势的DELETE 语句删除了表中全部记录后可以撤消:
MySQL数据库技术(08)
? ? 在此情形下,序列重新从1开始而不按严峻的增量次序持续增添.即便在C R E AT ETABLE 语句中明确指定了一个初始的序列编号,呼应的序列也会重新开始.呈现这种情形的缘由在于MySQL 优化完好删空一个表的DELETE 语句的办法上;它重新开始重新成立数据文件和索引文件而不是去删除每个记录,这样就丧失了全部的序列号信息.假如要删除全部记录,但但愿保存序列信息,可以撤消优化并强迫MySQL 履行逐行的删除操作,以下所示:
MySQL数据库技术(08)
? ? 假如利用的是3 . 2 3以上的版本,怎样保持严峻的增量序列?办法之一是保持一个只用来生成A U TO_INCREMENT 值的独立的表,永久不从这个表中删除记录.在这种情形下,独立表中的值永久不会重用.在主表中需求生成一个新记录时,首先在序列编号表中插入一个N U L L.然后对但愿包含序列编号的列利用L A S T _ I N S E RT_ID( ) 的值将该记录插入主表,以下所示:
MySQL数据库技术(08)
? ? 假如想要编写一个生成A U TO_INCREMENT 值的利用程序,但但愿序列从100 而不是1开始.再假定但愿这个程序可移植到全部MySQL 版本.怎样来完成它呢?假如可移植是一个目标,那么不能依靠MySQL 3.23 所供应的在C R E ATE TABLE 语句中指定初始序列编号的功效.而是在想要插入一个记录时,首先用下列语句查抄表能否是空的:
MySQL数据库技术(08)
? ? 这个步骤固然是附加的,但不会耗费太多的时间,因为没有WHERE 子句的SELECT COUNT(*) 是优化的,返回很快.假如表是空的,则插入记录并明确地对序列编号列指定值1 0 0.假如表不空,则对序列编号列值指定NULL 使MySQL 自动生成下一个编号.此办法答应插入序列编号为1 0 0、101 等的记录,它不管MySQL 能否答应指定初始序列值都能正常工作.假如要求序列编号即便是从表中删除了记录后也要严峻递增,则此办法不起作用.在这样的情形下,可将此办法与前面描写的什么也不做只是用来产生用于主表的序列编号的帮助表技术结合利用.为什么会但愿从一个大于1 的序列编号开始呢?一个缘由是想使全部序列编号全都具有相同的数字位数.假如需求生成顾客ID 号,并且但愿不要多于一百万个顾客,则可以从1 000 000
开始编号.在对顾客ID 值计数的数字位数改变之前,可以追加一百万个顾客.当然,强迫序列编号为一个固定宽度的另一个办法是采取ZEROFILL 列.关于有的情形,这样做有大概会出问题.比方,假如在Perl 或PHP 脚本中处理具有前导零的序列编号,则必须细心地将它们只作为串利用;假如将它们转换成数字,前导零将会丧失.下面的短Perl 脚本阐明了处理编号时大概会出的问题:
MySQL数据库技术(08)
? ? 打印时,此脚本给出下列输出:
MySQL数据库技术(08)
? ? P e r l’s‘+ +’自动增量操作是很机灵的并且可以操纵串或数值成立序列值,但‘+ =’操作只利用于数值.在所显示的输出中,可看到‘ + =’惹起串到数值的转换并且丧失了$s 值中的前导零.
? ? 序列不从1开始的另一个缘由从技术的角度来说大概不值一提.比方,在分配会员号时,序列号不要从1开始,免得呈现关于谁是第一号的政治争辩.
? ? (4) 不用A U TO_INCREMENT 生成序列生成序列号的另一个办法根本就不需求利用A U TO_INCREMENT 列.它操纵取一个参数的L A S T _ I N S E RT_ID( ) 函数的变量来生成序列号.(这种情势在MySQL 3.22.9. 中引入)假如操纵L A S T _ I N S E RT_ID(expr) 来插入或更新一个列, 则下一次不用参数调用L A S T _ I N S E RT_ID( ) 时,将返回expr 的值.换句话说,就像由A U TO_INCREMENT 机制生成的那样对expr 举行处理.这样使得能生成一个序列号,然后可在今后的客户会话中操纵它,用不着取受其他客户机影响的值.操纵这种战略的一种办法是成立一个包含一个值的单行表,该值在想得到序列中下一个值时举行更新.比方,可成立以下的表:
MySQL数据库技术(08)
? ? 上面的语句成立了表seq_table 并用包含seq 值0 的行对其举行初始化.可操纵这个表产生下一个序列号,以下所示:
MySQL数据库技术(08)
? ? 该语句取出seq 列的当前值并对其加1,产生序列中的下一个值.操纵L A S T _ I N S E RT _ID(seq + 1) 生成新值使它就像一个AUTO_INCREMENT 值一样,并且此值可在今后的语句中通过调用无参数的L A S T _ I N S E RT_ID( ) 来取出.即便某个其他客户机同时生成了另一个序列号,上述作用也不会改变,因为L A S T _ I N S E RT_ID( ) 是客户机专用的.假如但愿生成增量不是1 的编号序列或负增量的编号序列,也可以操纵这个办法.比方,下面两个语句可以用来辨别生成一个增量为100 的编号序列和一个负的编号序列:
MySQL数据库技术(08)
? ? 通过将seq 列设置为呼应的初始值,可操纵这个办法生成以肆意值开始的序列.关于将此序列生成办法用于多个计数器的利用,可参阅第3章.
? ? 2.2.3 串列范例
? ? MySQL 供应了几种存放字符数据的串范例.串常常用于以下这样的值:
MySQL数据库技术(08)
? ? 在某种意义上,串实际是一种"通用"范例,因为可用它们来表示肆意值.比方,可用串范例来存储二进制数据,如影像或声音,大概存储gzip 的输出后果,即存储紧缩数据.关于全部串范例,都要剪裁太长的值使其合适于呼应的串范例.但是串范例的取值范围很差别,有的取值范围很小,有的则很大.取值大的串范例可以存储近4GB 的数据.因此,应当使串充足长免得您的信息被堵截(由于受客户机/服务器通信协议的最大块尺寸限制,列
值的最大限额为2 4 M B).
? ? 表2 - 8给出了MySQL 定义串值列的范例,以及每种范例的最大尺寸和存储需求.关于可变长的列范例,各行的值所占的存储量是差别的,这取决于实际存放在列中的值的长度.这个长度在表顶用L 表示.
MySQL数据库技术(08)
? ? L 以外所需的额外字节为存放该值的长度所需的字节数.MySQL 通过存储值的内容及其长度来处理可变长度的值.这些额外的字节是无标记整数.请注意,可变长范例的最大长度、此范例所需的额外字节数以及占用相同字节数的无标记整数之间的对应关系.比方,
MEDIUMBLOB 值大概最多22 4 - 1字节长并需求3 个字节记录后来果.3 个字节的整数范例MEDIUMINT 的最大无标记值为22 4 - 1.这并非无意.
? ? 1. CHAR 和VARCHAR 列范例
? ? CHAR 和VARCHAR 是最常利用的串范例.它们是有差别的, CHAR 是定长范例而VARCHAR 是可变长范例.CHAR(M) 列中的每个值占M 个字节;短于M 个字节的值存储时在右边加空格(但右边的空格在检索时去掉).VARCHAR(M) 列的值只用所必须的字节数来存放(末尾的空格在存储时去掉,这与ANSI SQL 的VARCHAR 值的尺度差别),然后再加一个字节记录其长度.假如所需的值在长度上改变不大,则CHAR 是一种比VARCHAR 好的挑选,因为处理行长度固定的表比处理行长度可变的表的效率更高.假如全部的值长度相同,由于需求额外的字节来记录值的长度,VARCHAR 实际占用了更多的空间.在MySQL 3.23 从前,CHAR 和VARCHAR 列用最大长度为1 到255 的M 来定义.从MySQL 3.23 开始,CHAR(0) 也是合理的了.在但愿定义一个列,但由于尚不知道其长度,所以不想给其分配空间的情形下, CHAR(0) 列作为占位符很有效处.今后可以用A LT E RTABLE 来加宽这个列.假如答应其为N U L L,则CHAR(0) 列也可以用来表示o n / o ff 值.这样的列大概取两个值,NULL 和空串.CHAR(0) 列在表中所占的空间很小,只占一位.除少数情形外,在同一个表中不能混用CHAR 和VA R C H A R.MySQL 按照情形乃至会将列从一种范例转换为另一种范例.这样做的缘由以下:
? ? ■ 行定长的表比行可变长的表简单处理(其来由请参阅2 . 3节"挑选列的范例").
? ? ■ 表行只在表中全部行为定长范例时是定长的.即便表中只有一列是可变长的,该表的行也是可变长的.
? ? ■ 因为在行可变长时定长行的性能长处完好失去.所认为了节俭存储空间,在这种情形下最好也将定长列转换为可变长列.这表示,假如表中有VARCHAR 列,那么表中不大概同时有CHAR 列;MySQL 会自动地将它们转换为VARCHAR 列.比方成立以下一个表:
MySQL数据库技术(08)
? ? 请注意,VARCHAR 列的呈现使MySQL 将c1 也转换成了VARCHAR 范例.假如试图用A LTER TABLE 将c1 转换为C H A R,将不起作用.将VARCHAR 列转换为CHAR 的惟一办法是同时转换表中全部VARCHAR 列:
MySQL数据库技术(08)
? ? BLOB 和TEXT 列范例像VARCHAR 一样是可变长的,但是它们没有定长的等价范例,因此不能在同一表中与BLOB 或TEXT 列一同利用CHAR 列.这时任何CHAR 列都将被转换为VARCHAR 列.定长与可变长列混用的情形是在CHAR 列短于4 个字符时,可以不对其举行转换.比方,MySQL 不会将下面所成立的表中的CHAR 列转换为VARCHAR 列:
MySQL数据库技术(08)
? ? 短于4个字符的列不转换的缘由是,平均情形下,不存储尾空格所节俭的空间被VA R C H A R列中记录每个值的长度所需的额外字节所抵消了.实际上,假如全部列都短, MySQL 将会把所定义的全部列从VARCHAR 转换为C H A R.MySQL 这样做的缘由是,这种转换平均来说不会增添存储需求,并且使表行定长,从而改进了性能.假如按以下成立一个表,VARCHAR 列全城市转换为CHAR 列:
MySQL数据库技术(08)
MySQL数据库技术(08)
? ? 2. BLOB 与TEXT 列范例
? ? BLOB 是一个二进制大对象,是一个可以存储大量数据的容器,可以使其肆意大.在MySQL 中,BLOB 范例实际是一个范例系列( T I N Y B L O B、B L O B、M E D I U M B L O B、L O N G B L O B),除了在可以存储的最大信息量上差别外(请参阅表2 - 8),它们是平等的.
? ? MySQL 还有一个TEXT 范例系列( T I N Y T E X T、T E X T、M E D I U M T E X T、L O N G T E X T).除了用于对比和排序外,它们在各个方面都与呼应的BLOB 范例平等,BLOB 值是辨别大小写的,而TEXT 值不辨别大小写.BLOB 和TEXT 列关于存储大概有很大增长的值或各行大小有很大改变的值很有效,比方,字处理文档、图象和声音、混合数据以及新闻文章等等.BLOB 或TEXT 列在MySQL 3.23 以上版本中可以举行索引,固然在索引时必须指定一个用于索引的约束尺寸,免得成立出很大的索引项从而抵消索引所带来的好处.除此之外,普通不通过查找BLOB 或TEXT 列来举行搜索,因为这样的列常常包含二进制数据(如图象).常见的做法是用表中别的的列来记录有关BLOB 或TEXT 值的某种标识信息,并用这些信息来肯定想要哪些行.利用BLOB 和TEXT 列需求分外注意以下几点:
? ? ■ 由于BLOB 和TEXT 值的大小改变很大,假如举行的删除和更新很多,则存储它们的
表呈现高碎片率会很高.应当按期地运行OPTIMIZE TABLE 削减碎片率以保持杰出的
性能.要理解更具体的信息请参阅第4章.
? ? ■ 假如利用非常大的值,大概会需求调整服务器增添max_allowed_packet 参数的值.具体的信息请参阅第11章"通例的MySQL 管理".假如需求增添但愿利用非常大的值的客户机的块尺寸,可见附录E"MySQL 程序参考",该附录介绍了怎样对mysql 和mysqldump 客户机举行这种块尺寸的增添.
? ? 3. ENUM 和SET 列范例
??ENUM 和SET 是一种特别的串范例,其列值必须从一个固定的串集合挑选.它们之间的主要差别是ENUM 列值必须确切是值集合的一个成员,而SET 列值可以包含调集合肆意或全部的成员.换句话说, ENUM 用于彼此排挤的值,而S E T列可以从一个值的列表中挑选多个值.
? ? ENUM 列范例定义了一个列举.可赋予ENUM 列一个在成立表时指定的值列表中挑选的成员.列举可具有最多65 536 个成员(此中之一为MySQL 保存).列举普通用来表示类别值.比方,定义为E N U M ("N", "Y") 的列中的值可以是"N"或"Y".大概可将ENUM 用于诸如调查或问卷中的多项挑选问题,或用于某个产品的大概尺寸或颜色等:
MySQL数据库技术(08)
? ? 假如正在处理Web 页中的挑选,那么可以操纵ENUM 来表示站点拜候者在某页上的彼此排挤的单选钮调集合举行的挑选.比方,假如运行一个在线比萨饼订购服务系统,可用ENUM 来表示顾客订购的比萨饼形状:
MySQL数据库技术(08)
? ? 假如列举类别表示计数,在成立该列举时最重要的是挑选符合的类别.比方,在记录实行室查验中白血球的数目时,大概会将计数分为以下的几组:
MySQL数据库技术(08)
? ? 在某个测试后果以切确的计数到达时,要按照该值所属的类别来记录它.但假如想将列从基于类别的ENUM 转换为基于切确计数的整数时,不大概恢答复来的计数.在成立SET 列时,要指定一个合理的调集成员列表.在这种意义上, SET 范例与E N U M是近似的.但是SET 与ENUM 差别,每个列值可由来自调集合肆意数目的成员构成.调集合最多可有64 个成员.关于值之间互斥的固定调集,可以利用SET 列范例.比方,可操纵SET 来表示汽车的可用选件,以下所示:
MySQL数据库技术(08)
? ? 然后,特定的SET 值将表示顾客实际订购哪些选件,以下所示:
MySQL数据库技术(08)
  空串表示顾客未订购任何选件.这是一个合理的SET 值.SET 列值为单个串.假如某个值由多个调集成员构成,那么这些成员在串顶用逗号脱离.明显,这表示不该该用含有逗号的串作为SET 成员.SET 列的其他用处是表示诸如病人的诊断或来自Web 页的挑选后果这样的信息.关于诊断,大概会有一个向病人发问的尺度症状清单,而病人大概会表现出某些症状或全部的症状.关于在线比萨饼服务系统,用于订购的Web 页应当具有一组复选框,用来表示顾客想在比萨饼上加的配料.对ENUM 或SET 列的合理值列表的定义很重要,比方:
  ■ 正如上面所介绍的,此列表决意了列的大概合理值.
  ■ 可按肆意的大小写字符插入ENUM 或SET 值,但是列定义中指定的串的大小写字符决意了今后检索它们时的大小写.比方,假若有一个E N U M ("Y", "N") 列,但您在此中存储了" y"和"n",当您检索出它们时显示的是" Y"和"N".这并不影响对比或排序的状况,因为ENUM 和SET 列是不辨别大小写的.
  ■ 在ENUM 定义中的值次序就是排序次序.SET 定义中的值次序也决意了排序次序,但是这个关系更为复杂,因为列值大概包含多个调集成员.
  ■ SET 定义中的值次序决意了在显示由多个调集成员构成的SET 列值时,子串呈现的次序.
  ENUM 和SET 被归为串范例是由于在成立这些范例的列时,列举和调集成员被指定为串.但是,这些成员在内部存放时作为数值,并且一样可作为数值来处理.这表示ENUM 和S E T范例比其他的串范例更为有效,因为普通可用数值运算而不是串运算来处理它们.并且这还表示ENUM 和SET 值可用在串或数值的环境中.
? ? 列定义中的ENUM 成员是从1 开始次序编号的.(0 被MySQL 用作错误成员,假如以串的情势表示就是空串.)列举值的数目决意了ENUM 列的存储大小.一个字节可表示256 个值,两个字节可表示65 536 个值.(可将其与一字节和两字节的整数范例T I N Y I N T、
UNSIGNED 和SMALLINT UNSIGNED 举行比较.)因此,列举成员的最大数目为65 536(包含错误成员),并且存储大小依靠于成员数目能否多于256 个.在ENUM 定义中,可以最多指定65 535(而不是65 536)个成员,因为MySQL 保存了一个错误成员,它是每个列举的隐含成员.在将一个不法值赋给ENUM 列时,MySQL 自动将其换成错误成员.下面有一个例子,可用mysql 客户机程序测试一下.它给出列举成员的数值次序,并且还阐明了NULL 值无次序编号:
MySQL数据库技术(08)
? ? 可对ENUM 成员按名大概按编号举行运算,比方:
MySQL数据库技术(08)
? ? 可以定义空串为一个合理的列举成员.与列在定义中的其他成员一样,它将被赋予一个非零的数值.但是利用空串大概会惹起某些混合,因为该串也被作为数值为0 的错误成员.在下面的例子中,将不法的列举值" x"赋予ENUM 列惹起了错误成员的赋值.仅在以数值
情势举行检索时,才可以与空串区脱离:
MySQL数据库技术(08)
? ? SET 列的数值表示与ENUM 列的表示有所差别,调集成员不是次序编号的.每个成员对应SET 值中的一个二进制位.第一个调集成员对应于0 位,第二个成员对应于1 位,如此等等.数值SET 值0 对应于空串.SET 成员以位值保存.每个字节的8 个调集值可按此方法存
放,因此SET 列的存储大小是由调集成员的数目决意的,最多64 个成员.关于大小为1 到8、9 到1 6、17 到2 4、25 到3 2、33 到64 个成员的调集,其SET 值辨别占用1、2、3、4 或8个字节.
? ? 用一组二进制位来表示SET 恰是答应SET 值由多个调集成员构成的缘由.值中二进制位的肆意组合都可以得到,因此,呼应的值可由对应于这些二进制位的SET 定义中的串组合构成.下面给出一个阐明SET 列的串情势与数值情势之间关系的样例;数值以十进制情势和二
进制情势辨别给出:
MySQL数据库技术(08)
? ? 假如给SET 列赋予一个含有未作为调集成员列出的子串的值,那么这些子串被删除,并将包含别的子串的值赋予该列.在赋值给SET 列时,子串不需求按定义该列时的次序给出.但是,在今后检索该值时,各成员将按定义时的次序列出.假定用下面的定义定义一个S E T列来表示家具:
MySQL数据库技术(08)
? ? 假如给这个列赋予" c h a i r, couch, table"值,那么,"c o u c h"被放弃,因为它不是调集的成员.其次,今后检索这个值时,显示为" table, chair".之所以这样是因为MySQL 针对所赋的值的每个子串决意各个二进制位并在存储值时将它们置为1."c o u c h"不对应二进制位,则忽视.在检索时,MySQL 按次序扫描各二进制位,通过数值值构造出串值,它自动地将子串排成定义列时给出的次序.这个举措还表示,假如在一个值中不止一次地指定某个成员,但在检索时它也只会呈现一次.假如将" lamp, lamp,lamp"赋予某个SET 列,检索时也只会得出"l a m p".MySQL 重新对SET 值中的成员举行排序这个事实表示,假如用一个串来搜索值,则必须以精确的次序列出各成员.假如插入" c h a i r, table",然后搜索"c h a i r, table",那么将找不到呼应的记录;必须查找" table, chair"才能找到.ENUM 和SET 列的排序和索引是按照列值的内部值(数值值)举行的.下面的例子大概会显示不精确,因为各个值并非按字母次序存储的:
MySQL数据库技术(08)
MySQL数据库技术(08)
? ? NULL 值排在其他值前(假如是降序,将排在其他值之后).假若有一个固定的值集,并且但愿按特别的次序举行排序,可操纵ENUM 的排序次序.在成立表时做一个ENUM 列,并在该列的定义中以所想要的次序给出各列举值便可.假如但愿ENUM 按正常的字典次序排序,可以利用C O N C AT( ) 和排序后果将列转换成一个非ENUM 串,以下所示:
MySQL数据库技术(08)
? ? 4. 串列范例属性
? ? 可对CHAR 和VARCHAR 范例指定B I N A RY 属性使列值作为二进制串处理(即,在对比和排序操作辨别大小写).
? ? 可对任何串范例指定通用属性NULL 和NOT NULL.假如二者都不指定,缺省值为N U L L.但是定义某个串列为NOT NULL 并不禁止其取空串.空值差别于遗漏的值,因此,不要错误地认为可以通过定义NOT NULL 来强迫某个串列只包含非空的值.假如要求串值非
空,那么这是一个在利用程序中必须强迫实施的约束条件.
? ? 还可以对除BLOB 和TEXT 范例外的全部串列范例用D E FA U LT 属性指定一个缺省值.假如不指定缺省值, MySQL 会自动挑选一个.关于可以包含NULL 的列,其缺省值为N U L L.关于不能包含NULL 的列,除ENUM 列外都为空串,在ENUM 列中,缺省值为第一个列举成员(关于SET 范例,在呼应的列不能包含NULL 时其缺省值实际上是空集,不过这里空集等价于空串).
? ? 2.2.4 日期和时间列范例
? ? MySQL 供应了几种时间值的列范例,它们辨别是: DATE、DATE TIME、TIME、TIMES TAMP 和YEAR.表2-9 给出了MySQL 为定义存储日期和时间值所供应的这些范例,并给出了每种范例的合理取值范围.YEAR 范例是在MySQL 3.22版本中引入的.其他范例在全部MySQL 版本中都可用.每种时间范例的存储需求见表2 - 1 0.每个日期和时间范例都有一个"零"值,在插入该范例的一个不法值时替换成此值,见表2 - 11.这个值也是定义为NOT NULL 的日期和时间列的缺省值.
MySQL数据库技术(08)
MySQL数据库技术(08)
? ? MySQL 表示日期时按照ANSI 标准首先给出年份.比方,1999 年12 月3 日表示为"1 9 9 9 - 1 2 - 0 3".MySQL 答应在输入日期
时有某些活动的余地.如能将两个数字的年份转换成四位数字的年份,并且在输入小于10 的月份和日期时不用输入前面的那位数字.但是必须首先给出年份.普通常常利用的那些格局,如" 1 2 / 3 / 9 9"或"3 / 1 2 / 9 9",都是不精确的.MySQL 利用的日期表示法则请参阅"处理日期和时间列"小节.时间值按本地时区返回给服务器; MySQL 对返回给客户机的值不作任什么时刻区调整.
? ? 1. DATE、TIME 和DATETIME 列范例DATE、TIME 和DATETIME 范例存储日期、时间以及日期和时间值的组合.其格局为"YYYY - MM - DD"、"h h : m m : s s"和"YYYY - MM - DD hh:mm:ss".关于D ATETIME 范例,日期和时间部份都需求;假如将D ATE 值赋给DATETIME 列,MySQL 会自动地追加一个为"0 0 : 0 0 : 0 0"的时间部份.MySQL 对D ATETIME 和TIME 表示的时间在处理上稍有差别.关于D ATETIME ,时间部份表示某天的时间.而TIME 值表示占用的时间(这也就是为什么其取值范围如此之大并且答应取负值的缘由).用TIME 值的最右边部份表示秒,因此,假如插入一个"短"(不完好)的时间值,如"1 2 : 3 0"到TIME 列,则存储的值为" 0 0 : 1 2 : 3 0",即被认为是"12 分30 秒".假如乐意,也可用TIME 列来表示天的时间,但是要记着这个转换法则免得出问题.为了插入一个"12 小时30 分钟"的值,必须将其表示为" 1 2 : 3 0 : 0 0".
? ? 2. TIMESTAMP 列范例
? ? TIMES TAMP 列以YYYYMMDDhhmmss 的格局表示值,其取值范围从19700101000000到2037 年的某个时间.此取值范围与Unix 的时间相接洽,在UNIX 的时间中,1970 年的第一天为"零天",也就是所谓的"新纪元".因此1970 年的开始决意了T I M E S TAMP 取值范围的低端.其取值范围的上端对应于UNIX 时间上的四字节边界,它可以表示到2037年的值.(TIMES TAMP 值的上限将会随着操作系统为扩大UNIX 的时间值所举行的改正而增添.这是在系统库一级必须说起的.MySQL 也将操纵这些更改.)TIMES TAMP 范例之所以得到这样的名称是因为它在成立或改正某个记录时,有特别的记录作用.假如在一个TIMES TAMP 列中插入NULL,则该列值将自动设置为当前的日期和时间.在成立或更新一行但不明确给TIMES TAMP 列赋值时也会自动设置该列的值为当前的日期和时间.但是,仅行中的第一个TIMES TAMP 列按此方法处理,即便是行中第一个TIMESTAMP列,也可以通过插入一个明确的日期和时间值到该列(而不是NULL)使该处理失效.
MySQL数据库技术(08)
? ? TIMES TAMP 列的定义可包含对最大显示宽度M 的阐明.表2 - 1 2给出了所答应的M 值的显示格局.假如TIMES TAMP 定义中省略了M 大概其值为0或大于1 4,则该列按TIMES TAMP(14) 处理.取值范围从1到1 3的M 奇数值作为下一个更大的偶数值处理.T I M E S TAMP 列的显示宽度与存储大小或存储在内部的值无关.TIMES TAMP 值老是以4 字节存放并按14 位精度举行计算,与显示宽度无关.为了懂得这一点,按以下定义一个表,然后插入一些行,举行检索:
MySQL数据库技术(08)
? ? 从表面上看,呈现的行排序有误,第一列中的值全都相同,所以仿佛排序是按照第二列中的值举行的.这个表面反常的后果是由于事实上, MySQL 是按照插入T I M E S TAMP 列的全部14 位值举行排序的.MySQL 没有可在记录成立时设置为当前日期和时间、并此后今后保持不变的列范例.假如要实现这一点,可用两种办法来完成:
? ? ■ 利用T I M E S TAMP 列.在最初成立一个记录时,设置该列为N U L L,将其初始化为当前日期和时间:
MySQL数据库技术(08)
? ? 在今后无论什么时刻更改此记录,都要明确地设置此列为其原有的值.赋予一个明确的值使时间戳机制失效,因为它禁止了该列的值自动更新:
MySQL数据库技术(08)
? ? ■ 利用D ATETIME 列.在成立记录时,将该列的值初始化为NOW( ):
MySQL数据库技术(08)
? ? 无论今后什么时刻更新此记录,都不能动该列:U P D ATE tbl_name SET /* angthing BUT dt_col here */ WHERE ...假如想操纵T I M E S TAMP 列既保存成立的时间值又保存最后改正的时间值,那么可用一个T I M E S TAMP 列来保存改正时间值,用另一个T I M E S TAMP 列保存成立时间值.要保证保存改正时间值的列为第一个T I M E S TA M P,从而在记录成立或更改时自动对其举行设置.使保存成立时间值的列为第二个T I M E S TA M P,并在成立新记录时将其初始化为NOW( ).这样第二个T I M E S TAMP 的值将反映记录成立时间,并且今后将不再更改.
? ? 3. YEAR 列范例
? ? YEAR 是一个用来有效地表示年份值的1个字节的列范例.其取值范围为从1901 到2 1 5 5.在想保存日期信息但又只需求日期的年份时可以利用YEAR 范例,如诞生年份、政府机关推举年份等等.在不需求完好的日期值时, YEAR 比其另日期范例在空间操纵上更为有效.
YEAR 列的定义可包含显示宽度M 的阐明,显示宽度应当为4 或2.假如YEAR 定义中省略了M,其缺省值为4.TINYINT 与YEAR 具有相同的存储大小(一个字节),但取值范围差别.要利用一个整数范例且覆盖与YEAR 相同的取值范围,大概需求SMALLINT 范例,此范例要占两倍的空间.在所要表示的年份取值范围与YEAR 范例的取值范围相同的情形下, YEAR 的空间操纵率比SMALLINT 更为有效.YEAR 相对整数列的另一个长处是MySQL 将会操纵MySQL 的年份猜测法则把2 位值转换为4 位值.比方,97 与14 将转换为1997 和2 0 1 4.但要熟习到,插入数值00 将得到0000 而不是2 0 0 0.假如但愿零值转换为2 0 0 0,必须指定其为串"0 0".
MySQL数据库技术(08)
? ? 4. 日期和时间列范例的属性没有专门针对日期和时间列范例的属性.通用属性NULL 和NOT NULL 可用于肆意日期和时间范例.假如NULL 和NOT NULL 二者都不指定,则缺省值为N U L L.也可以用DEFA ULT 属性指定一个缺省值.假如不指定缺省值,将自动挑选一个缺
省值.含有NULL 的列的缺省值为NULL .不然,缺省值为该范例的"零"值.
? ? 5. 处理日期和时间列MySQL 可以理解各种格局的日期和时间值.D ATE 值可按背面的任何一种格局指定,此中包含串和数值情势.表2 - 1 3为每种日期和时间范例所答应的格局.两位数字的年度值的格局用"歧义年份值的注释"中所描写的法则来注释.关于有脱离
符的串格局,不一定非要用日期的" -"标记和时间的" :"标记来脱离,任何标点标记都可用作脱离符,因为值的注释取决于上下文,而不是取决于脱离符.比方,固然时间普通是用脱离符":"指定的,但MySQL 并不会在一个需求日期的上下文中将含有" :"号的值理解成时间.此外,关于有脱离符的串格局,不需求为小于10 的月、日、小时、分钟或秒值指定两个数值.下列值是完好平等的:
MySQL数据库技术(08)
? ? 请注意,有前导零的值按照它们被指定为串或数有差别的注释.串" 0 0 1 2 3 1"将视为一个六位数字的值并注释为D ATE 的"2 0 0 0 - 1 2 - 3 1"和D ATETIME 的"2000-12-31 00:00:00".而数0 0 1 2 3 1被认为1 2 3 1,这样的注释就有问题了.这种情形最好利用串值,大概假如要利用数值的话,应当用完好限定的值(即, D ATE 用2 0 0 0 1 2 3 1,D ATETIME 用2 0 0 0 1 2 3 1 0 0 0 0).普通,在D AT E、D ATETIME 和T I M E S TAMP 范例之间可以安闲地赋值,但是应当记着以下一些限制:
? ? ■ 假如将D ATETIME 或T I M E S TAMP 值赋给D AT E,则时间部份被删除.
? ? ■ 假如将D ATE 值赋给D ATETIME 或T I M E S TA M P,后果值的时间部份被设置为零.
? ? ■ 各种范例具有差别的取值范围.T I M E S TAMP 的取值范围更受限制( 1970 到2 0 3 7),因此,比方说,不能将1970 年从前的DATETIME 值赋给T I M E S TAMP 并得到公道的后果.也不能将2037 今后的值赋给TIMES TAMP.MySQL 供应了很多处理日期和时间值的函数.要理解更具体的信息请参阅附录C.
? ? 6. 歧义年份值的理解
? ? 关于全部包含年份部份的日期和时间范例( DATE、DATE TIME、TIME STAMP、YEAR),MySQL将两位数字的年份转换为四位数字的年份.这个转换按照下列法则举行(在MySQL4.0 中,这些法则稍有窜改,此中69 将转换为1969 而不是2069.这是按照X/Open UNIX 尺度规定的法则作出的窜改):
? ? ■ 00 到69 的年份值转换为2000 到2069.
? ? ■ 70 到99 的年份值转换为1970 到1999.
? ? 通过将差别的两位数字值赋给一个YEAR 列然后举行检索,可很简单地看到这些法则的效果.下面是检索程序:
MySQL数据库技术(08)
? ? 请注意,00 转换为0000 而不是2 0 0 0.这是因为0 是YEAR 范例的一个完好合理的值;假如插入一个数值,得到的就是这个后果.要得到2 0 0 0,应当插入串" 0"或"0 0".可通过C O N C AT( ) 插入YEAR 值来保证MySQL 得到一个串而不是数.C O N C AT( ) 函数不管其参数是串或数值,都返回一个串后果.请记着,将两位数字的年份值转换为四位数字的年份值的法则只产生一种后果.在未给
定世纪的情形下,MySQL 没有办法必定两位数字的年份的含义.假如MySQL 的转换法则不能得出您所但愿的值,办理的办法很简单:即用四位数字输入年份值.MySQL 有千年虫问题吗?MySQL 自身是没有2000 年问题的,因为它在内部是按四位数年份存储日期值的,并且由用户负责供应得当的日期值.两位数字年份注释的实际问题不是MySQL 带来的,而是由于有的人想费事,输入歧义数据所惹起的问题.假如您乐意冒险,可以持续这样做.在您冒险的时刻,MySQL 的猜设法则是可以利用的.但要意识到,很多时刻您确切需求输入四位数字的年份.比方, p r e s i d e n t表列出了1700 年以来的美国总统,所以在此表中录入诞生与死亡日期需求四位的年份值.这些列中的年份值跨了好几个世纪,因此,让MySQL 从两位数字的年份去猜想是哪个世纪是不大概的.

  以上是“MySQL数据库技术(08)[MySQL防范]”的内容,如果你对以上该文章内容感兴趣,你可以看看七道奇为您推荐以下文章:

  • Windows 搭配 IIS7 PHP MySQL 环境
  • mysql Out of memory (Needed 16777224 bytes)的错误办理
  • mysql提醒[Warning] Invalid (old?) table or database name问题的办理办法
  • mysql启用skip-name-resolve情势时呈现Warning的处理办法
  • mysql启用skip-name-resolve情势时呈现Warning的处理办法
  • MySQL Order By语法介绍
  • <b>MySQL ORDER BY 的实现解析</b>
  • mysql数据库插入速度和读取速度的调整记录
  • MySQL Order By索引优化办法
  • MySQL Order By用法分享
  • mysql #1062 –Duplicate entry ''1'' for key ''PRIMARY''
  • MySQL Order By Rand()效率解析
  • 本文地址: 与您的QQ/BBS好友分享!
    • 好的评价 如果您觉得此文章好,就请您
        0%(0)
    • 差的评价 如果您觉得此文章差,就请您
        0%(0)

    文章评论评论内容只代表网友观点,与本站立场无关!

       评论摘要(共 0 条,得分 0 分,平均 0 分) 查看完整评论
    Copyright © 2020-2022 www.xiamiku.com. All Rights Reserved .