初学者必看的MySQL坑
从业这些年,带过不少人、也接触过很多同事同行,发现新人甚至工作很多年的同事,对MySQL的部分原理都有相似的错误理解。
本文会持续整理出一些常见误区,希望能对大家的工作学习有帮助。
MySQL版本:5.6/5.7/8.x
真相列表
类型选择和字段设计
INT长度并不能指定
常见的int(4)
并不是指最大存储9999,而是低于4位的数字会使用空格或0在左侧补齐到4位。这个4是显示宽度。int
实际上是定长字段,占用4字节。取值范围固定是-(231-1) ~ (231-1) ,无符号时为0 ~ (232-1)。
延伸阅读:
VARCHAR存储的是字符而不是字节,但最大长度是另外的算法
VARCHAR
声明的是字符数,但存储的是字节。
理论上最大长度是65535 bytes,但实际上往往达不到。因为有几个因素:
-
65535是单行数据的最大值,实际上除了
varchar
,表里应该还会有其他字段 -
varchar
存放的字符串,往往会有多字节字符、一个字符占多个字节,而我们前端展现计算长度往往用的是字符数,所以也肯定达不到65535 -
varchar字段有长度标识位,可能占用1~2个字节,与我们声明的字段长度、字符集单字符最大长度有关,换算关系比较复杂,一句话说不清楚。
延伸阅读:
自增不一定连续,还可能重复
首先传递一个逻辑,MySQL InnoDB
的自增,是使用了一个表级的计数器。
自增不一定连续:如果insert或update指定了比当前最大值更大的值,计数器会直接增加到新的最大值;如果delete已有的一行数据,计数器并不会减小。
自增可能重复:上面提到的计数器,是维护在内存中的,MySQL一旦重启、又没有手工重新装载过计数器,新插入记录自增主键就会重新从最小值开始,就会出现重复。
TIMESTAMP只能表达68年
TIMESTAMP
以4字节整数(可看做SIGNED INT
)存储从1970-01-01T00:00:00Z
(UNIX纪元)经过的秒数。UNIX纪元看做0
值,小于纪元的时间插入会报错。
有符号4字节
可以表达最大绝对值为2^31-1
的数字,所以TIMESTAMP
的只能表达1970-01-01T00:00:01Z ~ 2038-01-19T03:14:07Z
的范围。
函数使用
count(column)
不会统计所有行
count(column)
会忽略掉值为NULL
的行,相比于count(*)
或count(1)
,统计出来的数字可能会小一些。从性能角度也不建议使用列。
更多
NULL
运算介绍和样例可参考《NULL如何参与运算和统计》
以上。感谢您的阅读。
持续更新中:
- 更多已知的MySQL误区
- 字符集问题
- 不走索引(扫描比)
- 扫描导致的更新慢
- 等等
- 读者反馈问题
原文地址:https://blog.csdn.net/zgdwxp/article/details/103378017