MySQL中的隐式主键和隐藏列
目录
开源示例
sql_generate_invisible_primary_key=on
sql_generate_invisible_primary_key=off
AliSQL
sql_generate_invisible_primary_key=off
思考?
注意事项
从MySQL 8.0.30 开始,MySQL支持为任何没有显式主键的InnoDB表生成不可见的主键。当sql_generate_invisible_primary_key服务器系统变量设置为ON
时,MySQL服务器会自动将生成的不可见主键(GIPK)添加到任何此类表中。此设置对使用除InnoDB
以外的任何其他存储引擎创建的表没有影响。
默认情况下,sql_generate_invisible_primary_key
的值为OFF
,这意味着GIPK的自动添加被禁用。
官方文档:https://dev.mysql.com/doc/refman/8.0/en/create-table-gipks.html
开源示例
MySQL 8.0.37
sql_generate_invisible_primary_key=on
sql_generate_invisible_primary_key=off
AliSQL
MySQL 8.0.36
sql_generate_invisible_primary_key=off
AliSQL有自研的参数show_ipk_info用来控制是否显示隐式主键的信息
思考?
那么为什么再上述sql_generate_invisible_primary_key=off的情况下依然会生成一个GEN_CLUST_INDEX聚集索引?
这是因为 InnoDB 存储引擎要求每个表必须有一个聚集索引。如果表中没有显式定义主键,也没有合适的唯一索引,InnoDB 会内部生成一个隐藏的聚集索引,通常命名为 GEN_CLUST_INDEX
。
这个隐藏的聚集索引是构建在一个包含行 ID 值的合成列上的,即使没有生成隐藏列,这个索引也会被创建以满足 InnoDB 对聚集索引的要求。因此,关闭 sql_generate_invisible_primary_key
选项并不影响聚集索引的自动创建,它只影响是否生成一个不可见的主键列。
row_id 再MVCC中有过介绍
https://www.yuque.com/eucalyptus-byepv/epkbe4/bgohmgh5m2w69p0z
注意事项
当sql_generate_invisible_primary_key=on时,创建的表有隐藏列`my_row_id`并且再该隐藏列上有primary key的情况下再去添加primary key是不被允许的
(1068, 'Multiple primary key defined')
并且删除隐藏列`my_row_id`和隐藏列`my_row_id`上的primary key都是不被允许的
(1235, "This version of MySQL doesn't yet support 'existing primary key drop without adding a new primary key. In @@sql_generate_invisible_primary_key=ON mode table should have a primary key. Please add a new primary key to be able to drop existing primary key.'")