MySQL数据库技术(08)
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 串列类型如表2 - 3所示。串可以存放任何内容,即使是像图像或声音这样的绝对二进制数据也可以存放。串在进行比较时可以设定是否区分大小写。此外,可对串进行模式匹配(实际上,在MySQL 中可以在任意列类型上进行模式匹配,但最经常进行模式匹配还是在串类型上)
日期与时间列类型在表2 - 4中示出。对于临时值, MySQL 提供了日期(有或没有时间)、时间和时间戳(一种允许跟踪对记录何时进行最后更改的特殊类型)的类型。而且还提供了一种在不需要完整的日期时有效地表示年份的类型。
要创建一个表,应使用C R E ATE TABLE 语句并指定构成表列的列表。每个列都有一个名字和类型,以及与每个类型相关的各种属性。下面是创建具有三个分别名为f、c 和i 的列的表my_table 的例子:
定义一个列的语法如下:
其中列名由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 提供了五种整型: 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 对这种类型不是可选的):
如果在创建表之后使用DESCRIBE my_table 语句,则输出的Field 和Type 列如下所示(注意,如果用MySQL 的3.23 以前的版本运行这个查询,则有一个小故障, 即BIGINT 的显示宽度将是21 而不是2 0。):
每一个数字列都具有一个由列类型所决定的取值范围。如果打算插入一个不在列范围内的值,将会进行截取: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的后三行说明了这一点。