mysql使用笔记(四)
一、选择合适的数据类型
1. CHAR vs VCHAR
char是固定长度的字符类型,而varchar是可变长度的字符类型。char(M)的数据列中,每个值都占用M个字节,如果某个长度小于M,mysql就会在它的右边用空格字符补足,在检索操作的时候最后一个非空格字符右边的所有字符都会被去掉,因此需要注意,去掉右边的空格有可能不只去掉补足的空格,还有可能去掉原来字符串中右边已有的空格!
在varchar(M)的数据列中,每个值只占用刚好够用的字节数再加上一个用来记录其长度的字节(即总长度为L+1个字节)。
由于char固定长度,因此处理速度比vchar快,但是占用空间比vchar大,在使用的时候需要具体情况具体分析,一般的原则是:
(1)对于myisam表,尽量使用char,对于那些经常需要修改而容易形成碎片的myisam和isam数据表就更是如此;
(2)对于innodb表,尽量使用varchar。
2. TEXT vs BLOB
保存少量字符串时使用char或varchar,而保存较大的文本时,选择text或者blob。二者的区别是blob还可以保存二进制数据,比如图片;而text只能保存纯文本数据。text和blob又分别细分为text,mediumtext,longtext和blob,mediumblob,longblob三种不同的长度类型。
blob和text值会引起一些性能问题,特别是在执行了大量的删除操作时。
删除操作会在数据表中留下很大的“空洞”,以后填入这些“空洞”的记录在插入的性能上会有影响。为了提高性能,建议定期使用 optimize table功能对这类表进行碎片整理,避免因为“空洞”导致性能问题。
可以使用合成的索引来提高大文本字段(blob或者text)的查询性能。合成索引就是根据大文本字段的内容建立一个散列值,并把这个值存储在单独的数据列中,接下来就可以根据检索散列值找到数据行。但是,这种技术只能用于精确匹配的查询(散列值对于类似<, >, >= 等范围搜索没有用)。
可以使用MD5(),SHA1(),CRC32()等来生成散列值。比如
create table t(id varchar(100), context blob, hash_value varchar(40)); insert into t values(1, repeate('beijing',2), md5(context)), (2, repeate('beijing',200), md5(context)), (100, repeate('helloworld',20), md5(context)); select * from t where hash_value=md5(repeat('beijing', 2));
如果需要对blob或text字段进行模糊匹配,mysql提供了前缀索引,即前缀%,比如select * from t where context='hello%'
。
3. 浮点数 vs 定点数
(1)浮点数存在表示误差,定点数采用字符串进行存储,精度高
(2)对货币等精度敏感的数据,应该采用定点数进行存储
(3)编程中,如果用到浮点数,要特别注意误差问题,并尽量避免做浮点数比较
(4)要注意浮点数中一些特殊值的处理
4. 日期类型选择
(1)要根据实际需要选择能够满足应用的最小存储的日期类型。比如,如果仅需要记录年份,则用1个字节来存储的YEAR,而不用考虑4个字节的DATE
(2)如果要记录日期和时间,且记录的年份久远,最好使用DATETIME而不是TIMESTAMP,因为DATETIME的范围比TIMESTAMP广
(3)如果记录的日期需要让不同时区的用户使用,最好使用TIMESTAMP,因为TIMESTAMP和实际时区匹配
二、 mysql中的字符集
常用字符集比较:
字符集 | 是否定长 | 编码方式 | 其他说明 |
---|---|---|---|
ASCII | 是 | 单字节7位编码 | 最早的奠基性字符 |
IOS-8859-1/latin1 | 是 | 单字节8位编码 | 西欧字符集 |
GB2312 | 是 | 双字节编码 | 早期标准,不推荐使用 |
GBK | 是 | 双字节编码 | 不少系统支持 |
GB18030 | 否 | 2字节或4字节编码 | 开始有一些支持,但数据库不常见 |
UTF-32 | 是 | 四字节编码 | UCS-4原始编码,现在很少使用 |
UCS-2 | 是 | 2字节编码 | |
UTF-16 | 否 | 2字节或4字节编码 | java和windows xp/nt等内部使用 |
UTF-8 | 否 | 1~4字节编码 | 互联网和unix/linux广泛支持的unicode字符集 |
其中,GBK每个汉字占用2个字节,而UTF-8每个汉字占用3个字节。