转至繁体中文版     | 网站首页 | 图文教程 | 资源下载 | 站长博客 | 图片素材 | 武汉seo | 武汉网站优化 | 
最新公告:     敏韬网|教学资源学习资料永久免费分享站!  [mintao  2008年9月2日]        
您现在的位置: 学习笔记 >> 图文教程 >> 数据库 >> MySql >> 正文
MySQL的列类型(5)         ★★★★

MySQL的列类型(5)

作者:闵涛 文章来源:闵涛的学习笔记 点击数:656 更新时间:2009/4/22 20:43:56
的列时,枚举和集合成员被指定为串。但是,这些成员在内部存放时作为数值,而且同样可作为数值来处理。这表示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 值无顺序编号:

    可对ENUM 成员按名或者按编号进行运算,例如:

    可以定义空串为一个合法的枚举成员。与列在定义中的其他成员一样,它将被赋予一个非零的数值。但是使用空串可能会引起某些混淆,因为该串也被作为数值为0 的错误成员。在下面的例子中,将非法的枚举值“ x”赋予ENUM 列引起了错误成员的赋值。仅在以数值
形式进行检索时,才能够与空串区分开:

    SET 列的数值表示与ENUM 列的表示有所不同,集合成员不是顺序编号的。每个成员对应SET 值中的一个二进制位。第一个集合成员对应于0 位,第二个成员对应于1位,如此等等。数值SET 值0 对应于空串。SET 成员以位值保存。每个字节的8 个集合值可按此方式存
放,因此SET 列的存储大小是由集合成员的数目决定的,最多64 个成员。对于大小为1到8、9 到16、17 到2 4、25 到3 2、33 到64 个成员的集合,其SET 值分别占用1、2、3、4 或8个字节。
    用一组二进制位来表示SET 正是允许SET 值由多个集合成员组成的原因。值中二进制位的任意组合都可以得到,因此,相应的值可由对应于这些二进制位的SET 定义中的串组合构成。下面给出一个说明SET 列的串形式与数值形式之间关系的样例;数值以十进制形式和二
进制形式分别给出:

    如果给SET 列赋予一个含有未作为集合成员列出的子串的值,那么这些子串被删除,并将包含其余子串的值赋予该列。在赋值给SET 列时,子串不需要按定义该列时的顺序给出。但是,在以后检索该值时,各成员将按定义时的顺序列出。假如用下面的定义定义一个S E T列来表示家具:

    如果给这个列赋予“ c h a i r, couch, table”值,那么,“c o uc h”被放弃,因为它不是集合的成员。其次,以后检索这个值时,显示为“ table, chair”。之所以这样是因为MySQL针对所赋的值的每个子串决定各个二进制位并在存储值时将它们置为1。“c o uc 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 列的排序和索引是根据列值的内部值(数值值)进行的。下面的例子可能会显示不正确,因为各个值并不是按字母顺序存储的:


    NULL 值排在其他值前(如果是降序,将排在其他值之后)。如果有一个固定的值集,并且希望按特殊的次序进行排序,可利用ENUM 的排序顺序。在创建表时做一个ENUM 列,并在该列的定义中以所想要的次序给出各枚举值即可。如果希望ENUM 按正常的字典顺序排序,可使用C O N C AT( ) 和排序结果将列转换成一个非ENUM 串,如下所示:

    4. 串列类型属性
    可对CHAR 和VARCHAR 类型指定B I N A RY 属性使列值作为二进制串处理(即,在比较和排序操作区分大小写)。
    可对任何串类型指定通用属性NULL 和NOT NULL。如果两者都不指定,缺省值为NULL。但是定义某个串列为NOT NULL 并不阻止其取空串。空值不同于遗漏的值,因此,不要错误地认为可以通过定义NOT NULL 来强制某个串列只包含非空的值。如果要求串值非
空,那么这是一个在应用程序中必须强制实施的约束条件。
    还可以对除BLOB 和TEXT 类型外的所有串列类型用D E FA U LT 属性指定一个缺省值。如果不指定缺省值, MySQL会自动选择一个。对于可以包含NULL 的列,其缺省值为NULL。对于不能包含NULL 的列,除ENUM 列外都为空串,在ENUM 列中,缺省值为第一个枚举成员(对于SET 类型,在相应的列不能包含NULL 时其缺省值实际上是空集,不过这里空集等价于空串)。
    2.2.4 日期和时间列类型
    MySQL提供了几种时间值的列类型,它们分别是: DATE、DATE TIME、TIME、TIMES TAMP 和YEAR。表2-9 给出了MySQL为定义存储日期和时间值所提供的这些类型,并给出了每种类型的合法取值范围。YEAR 类型是在MySQL3.22版本中引入的。其他类型在所有MySQL版本中都可用。每种时间类型的存储需求见表2 - 10。每个日期和时间类型都有一个“零”值,在插入该类型的一个非法值时替换成此值,见表2 - 11。这个值也是定义为NOT NULL 的日期和时间列的缺省值。


    MySQL表示日期时根据ANSI 规范首先给出年份。例如,1999 年12 月3 日表示为“1999 - 12 - 0 3”。MySQL允许在输入日期
时有某些活动的余地。如能将两个数字的年份转换成四位数字的年份,而且在输入小于10 的月份和日期时不用输入前面的那位数字。但是必须首先给出年份。平常经常使用的那些格式,如“ 12 / 3 / 9 9”或“3 / 12 / 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”。对于DATETIME 类型,日期和时间部分都需要;如果将DATE 值赋给DATETIME 列,MySQL会自动地追加一个为“0 0 : 0 0 : 0 0”的时间部分。MySQL对DATETIME 和TIME 表示的时间在处理上稍有不同。对于DATETIME ,时间部分表示某天的时间。而TIME 值表示占用的时间(这也就是为什么其取值范围如此之大而且允许取负值的原因)。用TIME 值的最右边部分表示秒,因此,如果插入一个“短”(不完全)的时间值,如“12 : 3 0”到TIME 列,则存储的值为“ 0 0 : 12 : 3 0”,即被认为是“12 分30 秒”。如果愿意,也可用TIME 列来表示天的时间,但是要记住这个转换规则以免出问题。为了插入一个“12 小时30 分钟”的值,必须将其表示为“ 12 : 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)使该处理失效。

    TIMES TAMP 列的定义可包含对最大显示宽度M 的说明。表2 - 12给出了所允许的M 值的显示格式。如果TIMES TAMP 定义中省略了M 或者其值为0或大于14,则该列按TIMES TAMP(14) 处理。取值范围从1到13的M 奇数值作为下一个更大的偶数值处理。T I M E S TAMP 列的显示宽度与存储大小或存储在内部的值无关。TIMES TAMP 值总是以4 字节存放并按14 位精度进行计算,与显示宽度无关。为了明白这一点,按如下定义一个表,然后插入一些行,进行检索:

    从表面上看,出现的行排序有误,第一列中的值全都相同,所以似乎排序是根据第二列中的值进行的。这个表面反常的结果是由于事实上, MySQL是根据插入T I M E S TAMP 列的全部14 位值进行排序的。MySQL没有可在记录建立时设置为当前日期和时间、并从此以后保持不变的列类型。如果要实现这一点,可用两种方法来完成:
    ■ 使用T I M E S TAMP 列。在最初建立一个记录时,设置该列为NULL,将其初始化为当前日期和时间:

    在以后无论何时更改此记录,都要明确地设置此列为其原有的值。赋予一个明确的值使时间戳机制失效,因为它阻止了该列的值自动更新:

    ■ 使用DATETIME 列。在建立记录时,将该列的值初始化为NOW( ):

    无论以后何时更新此记录,都不能动该列:UPDATEtbl_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 15 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 14。但要认识到,插入数值00 将得到0000 而不是2 0 0 0。如果希望零值转换为2 0 0 0,必须指定其为串“0 0”。

    4. 日期和时间列类型的属性没有专门针对日期和时间列类型的属性。通用属性NULL 和NOT NULL 可用于任意日期和时间类型。如果NULL 和NOT NULL 两者都不指定,则缺省值为NULL。也可以用DEFA ULT 属性指定一个缺省值。如果不指定缺省值,将自动选择一个缺
省值。含有NULL 的列的缺省值为NULL 。否则,缺省值为该类型的“零”值。
    5. 处理日期和时间列MySQL可以理解各种格式的日期和时间值。DATE 值可按后面的任何一种格式指定,其中包括串和数值形式。表2 - 13为每种日期和时间类型所允许的格式。两位数字的年度值的格式用“歧义年份值的解释”中所描述的规则来解释。对于有分隔
符的串格式,不一定非要用日期的“ -”符号和时间的“ :”符号来分隔,任何标点符号都可用作分隔符,因为值的解释取决于上下文,而不是取决于分隔符。例如,虽然时间一般是用分隔符“:”指定的,但MySQL并不会在一个需要日期的上下文中将含有“ :”号的值理解成时间。此外,对于有分隔符的串格式,不需要为小于10 的月、日、小时、分钟或秒值指定两个数值。下列值是完全等同的:

    请注意,有前导零的值根据它们被指定为串或数有不同的解释。串“ 0 0 12 3 1”将视为一个六位数字的值并解释为DATE 的“2 0 0 0 - 12 - 3 1”和DATETIME 的“2000-12-3100:00:00”。而数0 0 12 3 1被认为12 3 1,这样的解释就有问题了。这种情形最好使用串值,或者如果要使用数值的话,应该用完全限定的值(即, DATE 用2 0 0 0 12 3 1,DATETIME 用2 0 0 0 12 3 10 0 0 0)。通常,在DATE、DATETIME 和T I M E S TAMP 类型之间可以自由地赋值,但是应该记住以下一些限制:
    ■ 如果将DATETIME 或T I M E S TAMP 值赋给DATE,则时间部分被删除。
    ■ 如果将DATE 值赋给DATETIME 或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 列然后进行检索,可很容易地看到这些规则的效果。下面是检索程序:

    请注意,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从两位数字的年份去猜测是哪个世纪是不可能的。


没有相关教程
教程录入:mintao    责任编辑:mintao 
  • 上一篇教程:

  • 下一篇教程:
  • 【字体: 】【发表评论】【加入收藏】【告诉好友】【打印此文】【关闭窗口
      注:本站部分文章源于互联网,版权归原作者所有!如有侵权,请原作者与本站联系,本站将立即删除! 本站文章除特别注明外均可转载,但需注明出处! [MinTao学以致用网]
      网友评论:(只显示最新10条。评论内容只代表网友观点,与本站立场无关!)

    同类栏目
    · Sql Server  · MySql
    · Access  · ORACLE
    · SyBase  · 其他
    更多内容
    热门推荐 更多内容
  • 没有教程
  • 赞助链接
    更多内容
    闵涛博文 更多关于武汉SEO的内容
    500 - 内部服务器错误。

    500 - 内部服务器错误。

    您查找的资源存在问题,因而无法显示。

    | 设为首页 |加入收藏 | 联系站长 | 友情链接 | 版权申明 | 广告服务
    MinTao学以致用网

    Copyright @ 2007-2012 敏韬网(敏而好学,文韬武略--MinTao.Net)(学习笔记) Inc All Rights Reserved.
    闵涛 投放广告、内容合作请Q我! E_mail:admin@mintao.net(欢迎提供学习资源)

    站长:MinTao ICP备案号:鄂ICP备11006601号-18

    闵涛站盟:医药大全-武穴网A打造BCD……
    咸宁网络警察报警平台