数据类型的选择
CHAR与VARCHAR
CHAR和VARCHAR类型类似,都用来存储字符串,但它们保存和检索的方式不同。CHAR属于固定长度的字符类型,而VARCHAR属于可变长度的字符类型。
值 | CHAR(4) | 存储需求 | VARCHAR(4) | 存储需求 |
'' | ' ' | 4个字节 | '' | 1个字节 |
'ab' | 'ab ' | 4个字节 | 'ab' | 3个字节 |
'abcd' | 'abcd' | 4个字节 | 'abcd' | 5个字节 |
'abcdefgh' | 'abcd' | 4个字节 | 'abcd' | 5个字节 |
注意,如果MySQL运行在严格模式,超过列长度的值将不会保存,并且会出现错误提示。
从CHAR(4)和VARCHAR(4)列检索的值并不总是相同,因为检索时从CHAR列删除了尾部的空格。
由于CHAR是固定长度的,所以它的处理速度比VARCHAR快得多,但是其缺点是浪费存储空间,程序需要对行尾空格进行处理,所以对于那些长度变化不大并且查询速度又较高要求得数据可以考虑使用CHAR类型来存储。
随着MySQL版本得不断升级,VARCHAR数据类型的性能也在不断改进并提高。
不同的存储引擎对CHAR和VARCHAR的使用原则有所不同。
MyISAM存储引擎
建议使用固定长度的数据列代替可变长度的数据列
MEMORY存储引擎
目前都使用固定长度的数据行存储,因此无论使用CHAR或VARCHAR列都没有关系,两者都是作为CHAR类型处理。
InnoDB存储引擎
建议使用VARCHAR类型,对于InnoDB数据表,内部的行存储格式没有区分固定长度和可变长度列(所有数据行都使用指向数据列值的头指针)。因此在本质上,使用固定长度的CHAR列不一定比使用可变长度VARCHAR列性能要好。因而,主要的性能因素是数据行使用的存储总量。由于CHAR平均占有的空间多于VARCHAR,因此使用VARCHAR来最小化需要处理的数据行的存储总量和磁盘I/O是比较好的。
TEXT与BLOB
保存较大文本时,通常会选择使用TEXT或者BLOB,二者之间的主要差别是BLOB能用来保存二进制数据,而TEXT只能保存字符数据。
TEXT和BLOB中又分别包括TEXT、MEDIUMTEXT、LONGTEXT和BLOB、MEDIUMBLOB、LONGBLOB三种不同的类型,它们之间的主要区别是存储文本长度不同和存储字节不同,用户应该根据实际情况选择能够满足需求的最小存储类型。
BLOB和TEXT还存在一些需要注意的地方。
BLOB和TEXT值会引起一些性能问题,特别是在执行了大量的删除操作时。删除操作会在数据表中留下很大的“空洞”,以后填入这些“空洞”的记录在插入的性能上会有影响。为了提高性能,建议定期使用OPTIMIZE TABLE功能对这类表进行碎片整理,避免因为“空洞”导致性能问题。
可以使用合成的(Synthetic)索引来提高大文本字段(BLOB或TEXT)的查询性能。简单来说,合成索引就是根据大文本字段的内容建立一个散列值,并把这个值存储在单独的数据列中,接下来就可以通过检索散列值找到数据行了。要注意这种技术只能用于精确匹配的查询。
在不必要的时候避免检索大型的BLOB或TEXT值。
如果把BLOB或TEXT列分离到单独的表后,可以把原数据表中的数据列转换为固定长度的数据行格式,那么它就是有意义的。这会减少主表中的碎片,可以得到固定长度数据行的性能优势。它还可以使主数据表在运行SELECT * 查询的时候不会通过网络传输大量的BLOB或TEXT值。
浮点数与定点数
浮点数一般用于表示含有小数部分的数值。当一个字段被定义为浮点类型后,如果插入数据的精度超过该列定义的实际精度,则插入值会被四舍五入到实际定义的精度值,然后插入。
定点数不同于浮点数,定点数实际上是以字符形式存放的,所以定点数可以更精确地保存数据。如果实际插入的数值精度大于实际定义的精度,在某些SQLMode下MySQL会进行警告,然后按照实际精度四舍五入后插入,而在TRADITIONAL模式下,系统会直接报错,导致数据无法插入。
由于浮点数会产生误差,因此在精度要求比较高的应用中(比如货币)要使用定点数而不是浮点数来保存数据。
日期类型选择
根据实际需要选择能够满足应用的最小存储的日期类型。
如果要记录年月日时分秒,并且记录的年份比较久远,那么最好使用DATETIME,而不要使用TIMESTAMP。
如果记录的日期需要让不同时区的用户使用,那么最好使用TIMESTAMP,因为日期类型中只有它能够和实际时区相对应。
Last updated