整数类型
类型 | 存储空间 | 取值范围 |
---|---|---|
TINYINT | 8位 | -128~127 |
SMALLINT | 16位 | -32768~32767 |
MEDIUMINT | 24位 | -8388608~8388607 |
INT | 32位 | -2147483648~2147483647 |
BIGINT | 64位 | -9223372036854775808~9223372036854775807 |
这里不需要记忆取值范围,可以通过存储空间计算出来。
公式如下:
取
值
范
围
=
−
2
(
n
−
1
)
~
2
(
n
−
1
)
−
1
(
其
中
n
为
存
储
空
间
位
数
)
取值范围 = -2^{(n-1)} ~ 2 ^{(n-1)}-1\\ (其中n为存储空间位数)
取值范围=−2(n−1)~2(n−1)−1(其中n为存储空间位数)
整数类型有UNSIGNED属性,表示是否带有符号(是否允许负值)。如果不允许负值,取值范围的公式就变成了
取
值
范
围
=
0
~
2
∗
2
(
n
−
1
)
−
1
(
其
中
n
为
存
储
空
间
位
数
)
取值范围 = 0 ~ 2*2^{(n-1)}-1 \\ (其中n为存储空间位数)
取值范围=0~2∗2(n−1)−1(其中n为存储空间位数)
有符号和无符号的类型使用相同的存储空间,具有相同的性能。
Mysql可以为整数类型指定宽度,例如INT(11),这里的宽度不会限制字段的范围,只是规定了Mysql的一些交互工具用来现实字符的个数,所以一般使用默认的即可。对于存储和计算来说INT(1)和INT(11)是一样的。
实数类型
实数是带有小数部分的数字。
DECIMAL类型用户存储精确的小数,可以用来进行高精度的运算。
FLOAT和DOUBLE类型作为浮点类型,支持使用标准的浮点运算进行近似计算。
DECIMAL的高精度运算是由Mysql服务器实现的,运算性能上明显要低于CPU直接支持的浮点运算。
类型 | 存储空间 |
---|---|
Float | 32位(4字节) |
Double | 64位(8字节) |
Decimal | 72位(9字节) |
Decimal定义的时候有两个参数 Decimal(M,D)
- M 表示整个字段最多有多少个数字,范围1~65,默认为10
- D 表示小数点后有几位(D必须小于M),默认为0
举个例子,Decimal(3,1) 的取值范围 -99.9~99.9。
Decimal将数字打包保存到1个二进制字符串中,4个字节保存9个数字,小数点单独占用1个字节。
如果不到9个数字,占几个字节?看表格
数字个数 | 存储空间 |
---|---|
0 | 0字节 |
1-2 | 1字节 |
3-4 | 2字节 |
5-6 | 3字节 |
7-9 | 4字节 |
字符串
VARCHAR 用于存储 可变长 字符串,它只占用实际需要使用的空间。
由于时可变长的,所以需要额外有1~2个字节来记录实际使用长度。当最大长度小于等于255个字节(注意这里说的是字节)时,占用1个字节,此外使用2个字节。
缺点是当update时可能使行变得比原来长,这就需要做额外的工作。如果一个行变长,并且在页内没有更多的空间,Innodb会分裂页来是行可以放进当前页。
CHAR 是定长的字符串类型。Mysql每次会为CHAR分配足够的空间。
CHAR会删除所有末尾的空格,然后Mysql会根据需要使用空格来填充以方便比较。
需要注意的是,VARCHAR的长度定义是字符数,不是字节数。
常用的,utf8字符集下,1个字符最多占用3个字节。utf8mb4字符集下,1个字符最多占用4个字节。
类型 | 优点 | 缺点 | 适用 |
---|---|---|---|
VARCHAR | 可变长,节约空间 | 需要额外的1~2字节记录长度 更新频繁时易产生碎片 | 字符串最大长度比平均长度大很多 列更新少 适用字符集,每个字符都使用不同字节数进行存储 |
CHAR | 定长,不需要额外字段记录长度 不容易产生碎片 | 无论值的长短都会占满空间 | 存储比较短的字符串 所有值长度都差不多 经常需要变更的列 |
日期与时间
DATETIME能保存大范围的值,从1001年到9999年,精确到秒。它与时区无关,存储在8个字节的空间里,可排序。
TIMESTAMP保存了从1970年1月1日午夜以来的秒数,它和unix时间戳相同。TIMESTAMP只使用了4个字节,因此它的范围比DATETIME小的多,只能表示1970年到2038年。
TIMESTAMP可以配置默认值实现:如果在插入时没有指定值,设置这个列的值为当前时间,更新也是如此。
参考资料:
《高性能Mysql》
Mysql 官网