本篇主要是记录一下平时遇到的数字类型使用的问题
数字类型
| 类型 | 占用空间 | 最小值~最大值 |
|---|---|---|
| Tinyint | 1 | -128~127 |
| Smallint | 2 | -32768~32767 |
| Mediumint | 3 | -2²³ ~ 2²³-1 |
| int | 4 | -2³¹ ~ 2³¹-1 |
| Bigint | 8 | -2⁶³ ~ 2⁶³-1 |
这里可能要注意一下:signed 和 unsigned 的区别。默认是 signed,而且在使用中也不建议使用 unsigned。因为你在减的过程中可能为负数,这个就超出了 unsigned 的表示范围,就会出现:BIGINT UNSIGNED value is out of range in 这个错误:
可以通过
NO_UNSIGNED_SUBTRACTION:SET sql_mode='NO_UNSIGNED_SUBTRACTION';允许相减的结果为
signed,这样相减就对了。
浮点数和高精度
FloatDECIMAL(M,N)
对于 DECIMAL(M,N) 需要注意的是:
M是保存值的位数,也就是整个有多少位N才是标志小数点后保存的位数
同时在金融字段里面,不推荐使用 DECIMAL ,更推荐使用 BIGINT 。为什么呢?
DECIMAL实现是用二进制实现,不如 整型 来的高效- 同时
DECIMAL是一个变长字段,这个在存储行上会多余分配一个变长空间 - 在更新时,需要额外分配空间,造成碎片,同时和2结合
至于 float 这种浮点的,那就更不可能高精度了,这个存储本身就不真实,所以完全不建议在生产环境使用。
关于自增
直接说怎么做:
- 用
BIGINT做主键 - 自增值并不持久化,建议升级到
8以后
先说第一个:
一个类型能不能满足业务,先看他的表示范围,最大到 42亿,但是互联网的数据谁知道呢,很容易就超过这个表达限制,所以干脆直接升到 BIGINT
第二个是什么呢?
可能很疑惑,为什么自增还要持久化,mysql 不就是持久化嘛?简单来说,AUTO_INCREMENT 其实在每一次重新启动的时候,读取当前表最大的id,作为 AUTO_INCREMENT 的启动值,并存储在内存中,但是以下情况:
- 删除一条
- 并发插入时就会造成主键Id不连续
8之后 AUTO_INCREMENT 的变化会写入到 redo log 里面,所以出现问题或者是重启都可以从 redo log 中恢复,避免出现不单调的主键。