MySQL 数据类型

818 阅读5分钟

这是我参与更文挑战的第2天,活动详情查看: 更文挑战

前言

学习MySQL不能避开的就是数据类型,所有数据最终都要落到表中的数据字段中,选择正确的数据类型有助于提高数据库的效率。

1.选择优化的数据类型

更小的通常更好

一般情况下,应该尽量使用可以正确存储数据的最小数据类型。但是需要小心不要低估需要存储的值的范围。

简单就好

简单数据类型的操作通常需要更少的CPU周期,例如,整型比字符操作代价更低,因为字符集和校对规则(排序规则)使字符比较比整型比较更复杂。

尽量避免NULL

很多表都包含可为NULL(空值)的列。如果要建立索引的列,最好不要设计成可以为NULL的列,但是InnoDB使用单独的位(bit)来存储NULL,所以对于很多值为NULL,只有少数行的列有非NULL值的稀疏数据可能更好。 stackoverflow.com/questions/2…

2.整数类型

image.png

整数类型有可选的UNSIGNED属性,表示不允许负值,阿里巴巴里面规定如果是非负数,必须使用这个,数据库中表示是与否时,使用tinyint类型。
如果给字段加上了ZEROFILL(填充0)属性,那么MySQL 自动就会给列加上UNSIGNED 属性。 INT(11)中的11代表填充0的时候要填充几位0给不够位数的数字,实际上没有任何意义,8.0版本已经把它标记为过时了,之后有可能会剔除掉,如果想在左面补充0,可以使用LPAD()。
需要注意如果是int unsigned的时候,Java里面对应接收的要为Long 类型,不然有可能溢出。

3.实数类型

DECIMAL[18,6]代表总长18位,小数点后有6位小数,小数点前有12位,存储的时候是每四个字节存9个数字。小数点前用8个字节,小数点本身占1个字节,小数点后用4个字节。总长度最长是65位,小数位最长是30位。 FLOAT 用4个字节,DOUBLE用8个字节,相比DECIMAL用的空间更少,但是精度会有问题的,我一般都用DECIMAL。

4.字符串类型

VARCHAR用于存储可变长字符串,更节省空间,当然,如果MySQL使用ROW_FORMAT=FIXED创建的话,每一行都会定长存放,会比较浪费空间。
VARCHAR需要使用1或2个额外字节记录字符串长度,大于255字节的时候,会用两个字节来储存长度。
变长带来的问题是UPDATE时可能使行变得比原来更长,InnoDB则需要分裂页来使行可以放进页里,带来了一些额外的工作。
CHAR是定长的,适合储存很短的字符串,或者所有值都接近一个长度。阿里代码规范中要求存储的字符串长度几乎相等时,使用char。

5.BLOB和TEXT类型

用来存储很大的数据而设计的字符串数据类型,分别使用二进制和字符方式存储。BLOB值被视为二进制字符串(字节字符串)。它们具有binary字符集和排序规则,并且比较和排序基于列值中字节的数字值。 TEXT值被视为非二进制字符串(字符字符串)。它们具有binary以外的字符集,并且根据字符集的排序规则对值进行排序和比较。
由于BLOB和TEXT值可能非常长,使用磁盘会导致性能下降,因此仅在确实需要时在查询结果中包含BLOB或TEXT列。
例如,避免使用SELECT * ,它会选择所有列。

6.日期和时间类型

DATETIME类型

用于包含日期和时间部分的值。
MySQL 检索并以'YYYY-MM-DD hh:mm:ss'格式显示DATETIME值。 支持的范围是'1000-01-01 00:00:00'到'9999-12-31 23:59:59'。

TIMESTAMP数据类型

用于包含日期和时间部分的值。 TIMESTAMP的范围是'1970-01-01 00:00:01' UTC 到'2038-01-19 03:14:07' UTC。 DATETIME或TIMESTAMP值可以包含尾随的小数秒部分,精度最高为微秒(6 位数)。特别是,存储在DATETIME或TIMESTAMP列中的值中的任何小数部分都将被存储而不是被丢弃。包括小数部分,这些值的格式为'YYYY-MM-DD hh:mm:ss[.fraction]',DATETIME值的范围为'1000-01-01 00:00:00.000000'到'9999-12-31 23:59:59.999999',并且TIMESTAMP值的范围为'1970-01-01 00:00:01.000000'到'2038-01-19 03:14:07.999999'。小数部分应始终与其余时间用小数点分隔;没有其他小数秒分隔符被识别。

MySQL 将TIMESTAMP值从当前时区转换为 UTC 进行存储,然后从 UTC 转换回当前时区进行检索。 (对于其他类型,例如DATETIME,不会发生这种情况.)默认情况下,每个连接的当前时区是服务器的时间。可以在每个连接的基础上设置时区。只要时区设置保持不变,您将获得与存储相同的值。如果存储TIMESTAMP值,然后更改时区并检索该值,则检索到的值与您存储的值不同。发生这种情况是因为没有在两个方向上使用相同的时区进行转换。当前时区可用作time_zone系统变量的值。

总结

本文讲解了MySQL数据库中的各种数据类型。下次我们将会讲解MySQL多版本控制相关,敬请期待,下篇再见!