MySQL数据类型优化作者的故事本来以为mysql数据类型很简单很基础的知识,自以为掌握的差不多了。但是经过上次面试,发现自己把握的并不牢固,很多细节和原理都不知道。后来看了《高性能mysql》这本书,仔细看了第四章Schema和DataTypeOptimization。因此,写这篇文章记录总结,加深理解。选择优化的数据类型无论存储哪种类型,以下简单原则将有助于做出更好的选择越小通常越好,越简单尽量避免空整型数据类型存储空间TINYINT8位SMALLINT16位MEDINUMINT24位INT32位BIGINT64-bit取值范围:-2^(N-1)~2^(N-1)-1,N位存储空间的位数。整数类型有一个可选的UNSIGNED类型,这意味着不允许使用负值,这大约是正数上限的两倍。例如TINYINTUNSIGNED的存储范围是0~255,而TINYINT的存储范围是-128~127。有符号和无符号类型使用相同的存储空间,具有相同的性能,因此可以根据实际情况选择合适的类型。MySQL可以为整数类型指定宽度,例如INT(11),这对大多数应用程序没有意义。不会限制取值的合法范围,只规定MySQL的一些交互工具(如MySQL命令行客户端)用于显示字符数。INT(1)和INT(20)的存储和计算相同。实型、浮点型和DECIMAL型都可以指定精度。对于DECIMAL列,您可以指定小数点前后允许的最大位数。这会影响列的空间消耗。MySQL5.0及更高版本将数字打包成二进制字符串(每4个字节9个数字)。例如DECIMAL(18,9)存储小数点两边9个数,一共使用9个字节,小数点前后各4个字节,小数点各占1个字节。浮点类型通常使用比DECIMAL更少的空间来存储相同的值。FLOAT使用4个字节,DOUBLE使用8个字节,比FLOAT精度更高,范围更大。由于额外的空间和计算开销,您应该尝试仅将DECIMAL用于带小数的精确计算,例如存储财务数据。但是当数据量比较大的时候,可以考虑用BIGINT代替DECIMAL,根据小数位数,将要存储的值乘以相应的倍数。字符串类型VARCHAR和CHAR是最重要的字符串类型VARCHARVARCHAR主要用于存储变长字符串,比定长字符串更节省空间。有一个例外,如果MySQL表是用ROW_FORMAT=FIXED创建的,则每一行将以固定长度存储。VARCHAR需要使用1或2个额外字节来存储字符串的长度,如果列的最大长度<=255,则为1个字节,否则为2个字节。VARCHAR节省存储空间,对性能也有好处。但是因为行是变长的,更新的时候可能会使行比原来的行长,这就需要额外的工作。适用于VARCHAR的场景:字符串列的最大长度远大于平均长度;专栏更新较少。CHARCHAR类型是定长的,适合存储很短的字符串或者所有的值都接近相同的长度。例如MD5值非常适合存储密码。对于经常变化的列,CHAR比VARCHAR更合适。注意:使用VARCHAR(5)和VARCHAR(200)存储hello的空间开销是一样的,但是更长的列会消耗更多的内存,因为MySQL通常会分配一个固定大小的内存块来存储内部值。最好的策略是只分配真正需要的空间。日期和时间类型MySQL可以使用多种类型来保存时间和日期,例如YEAR和DATE,MySQL可以存储最小的时间粒度为秒。这里主要介绍两种类似的日期类型DATETIME和TIMESTAMP。数据类型存储空间时间范围DATETIME8bytes1001~9999TIMESTAMP4bytes1970~2038一般情况下尽量使用TIMESTAMP,比DATETIME更节省空间。有些人将unix时间戳存储为整数值,但这并没有带来任何好处(特殊情况除外,见下文),而且数据不方便处理,因此不推荐使用。对于需要存储粒度小于秒的日期时间值,建议使用BIGINT类型存储微秒级别的时间戳,或者使用DOUBLE类型存储秒后的小数部分。小结本文主要介绍MySQL常用的数据类型。如有错误或不准确之处,欢迎交流。
