暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

mysql字段数量限制为啥是1017 ?

原创 大大刺猬 2025-04-30
161

快放假了,水一篇.

背景

在使用mysql的时候, 可能会遇到需要创建很多列的表的情况, 那么最多能创建多少列呢?

查询官方文档发现一张表最多1017列(字段).
image.png

这个数字比较特殊, 不是1024这样的整数.

思考

其实我们查阅源码(storage/innobase/include/rem0types.h)就能发现如下定义:

# define REC_MAX_N_FIELDS (1024 - 1) # define REC_MAX_N_USER_FIELDS (REC_MAX_N_FIELDS - DATA_N_SYS_COLS * 2)

REC_MAX_N_FIELDS 表示最大字段数量为 1024 - 1 = 1023
而 REC_MAX_N_USER_FIELDS 表示用户能够使用的最大字段数量为1023 - 3*2 = 1017

为啥要减去3*2呢?

3(DATA_N_SYS_COLS) 表示内部字段: 有三个,如下:

DB_ROW_ID 没有主键的时候,创建一个6字节的rowid代替 DB_TRX_ID 事务id(6字节) DB_ROLL_PTR 回滚指针(7字节)

都是之前解析数据文件的时候的老朋友了.
image.png

为啥乘上2呢?
官网也有相关描述, 大意是跟mlog_parse_index有关.

mlog_parse_index() creates a dummy table object possibly, with some of the system columns in it,and then adds the 3 system columns (again) using dict_table_add_system_columns()

深度思考

看起来都是那么的有理有据, 细心的小伙伴可能发现了, 为啥REC_MAX_N_FIELDS是1024-1呢? 这个1024又是怎么来的呢?

在整理record header的时候发现了REDUNDANT行格式下的一个叫REC_N_FIELDS的信息(new style已经移除了). 该信息记录该数据行有多少个字段, 正好使用10bit, 也就是1024 和innodb的数据字段数量限制恰好吻合.

image.png

也就是在存储设计上就已经有了字段数量限制了, 后续的new style format(比如compact/DYNAMIC)之类的虽然去掉了rec_n_fileds,但为了兼容性,字段数量的限制还是没变. (毕竟正常情况很难达到1017个字段)

达到字段数量限制之后会提示: ERROR 1117 (HY000) at line 1: Too many columns 之前解析超多列的时候演示过了的, 这里就不再赘述了.

参考:

https://dev.mysql.com/doc/refman/8.0/en/innodb-limits.html
https://github.com/mysql/mysql-server/blob/trunk/storage/innobase/include/rem0types.h

「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论