MySQL online DDL 更改Varchar的字段长度
一、这里是可以跳过的牢骚
开年上班的第一个星期,周围的同事们都在“表面上努力的工作,朋友圈一打开都在祝福谷爱凌夺冠”,哈哈哈,比较闲啦。 今天研究了一下varchr长度变更会不会把表给锁了。
事情是这样的,我一直觉得自己是项目的后妈,在加入项目的时候,表结构的设计我的领导已经设计好了,我妥妥的CURD工具人。之后项目一直在迭代,需求也是面目全非的迭代升级(hhhh 这里有点夸张),导致我们表里很多代表一个意义的字段长度不太统一,想着年后第一周比较闲,我来把字段统一一下。
印象里对表进行alter操作,是会给表加上表锁的。原本我不紧不慢的在改着,直到把所有sql拉出来后,我的心有点虚了,这也太多了,要是数据大一点的表锁住了影响业务可怎么办?
然后开始想**“是不是不锁表”,我只是改个长度而已,varchar不是可以变长的存储吗?**
我开始查阅资料,嘿嘿,并且得到了如下图的手稿(反正我是理解了一些东西了,这篇文章呢,咱也是写给自己回顾用的):
二、这里是一些归纳总结
2.1 varchar(100) 这个100 代表什么?
版本 | 字符/字节 |
---|---|
4.0版本及以下版本 | 可存储的最大字节数 |
5.0版本及以上版本 | 可存储的最大字符数 |
2.2 修改Varchar 的大小的时候。不用锁表,就可以进行操作DDL是与版本有关系的
5.6版本不支持
5.7版本支持online DDL 但是存在前提
详情可以参考文章:
https://cloud.tencent.com/developer/article/1685988
2.3 5.7版本varchar扩长online DDL的前提是什么
这里先明确一个公式:
最大长度字符数 = (行存储最大字节数 - NULL标识列占用字节数 - 长度标识字节数 )/ 字符集(utf8/utf8mb4等)单字节最大字节数
行存储最大字节数 : 2^18 = 65535字节
NULL标识列占用字节数 : 1字节
长度标识字节数:[0,255] = 1字节 / [256,65535] = 2字节
字符集:
- GBK编码:一个英文字符占一个字节,中文2字节,单字符最大可占用2个字节。
- UTF-8编码:一个英文字符占一个字节,中文3字节,单字符最大可占用3个字节。
- utf8mb4编码:一个英文字符占一个字节,中文3字节,单字符最大占4个字节(如emoji表情4字节)。
由以上信息可以得到:
在某一列只有一个字段是varchar类型时,最大存储字符数为;
字符集 | 长度标识字节数为1字节最大存储字符数 | 长度标识字节数为1字节最大存储字符数 |
---|---|---|
GBK | 127 | / |
utf8 | 85 | / |
utf8mb4 | 63 | / |
长度标识字节数 255是一个界限,只要扩涨区间没有跨越这个界限 5.7版本就可以实现varchar onlind 变更
一但跨越长度标识字节数就要由1变为2