mysql columns表主键_请给你的Mysql(InnoDB)表加上主键吧

为什么一定要加主键?

对于Mysql数据库,现在一般用的都是InnoDB存储引擎,InnoDB的索引结构是B+Tree,B+Tree可以分为聚集索引和非聚集索引,在InnoDB里为聚集索引

在InnoDB中,表数据文件本身就是按B+Tree组织的一个索引结构,这棵树的叶节点data域保存了完整的数据记录。主键索引的key是数据表的主键,因此InnoDB表数据文件本身就是主索引

因为InnoDB的数据文件本身要按主键聚集,所以InnoDB要求表必须有主键(MyISAM可以没有)

没主键怎么办?

我们在建表时发现是可以不指定主键的,那没指定主键的表,Mysql是怎么处理的呢?

Mysql的官方文档是这么写的:

When you define a PRIMARY KEY on your table, InnoDB uses it as the clustered index. Define a primary key for each table that you create. If there is no logical unique and non-null column or set of columns, add a new auto-increment column, whose values are filled in automatically.

If you do not define a PRIMARY KEY for your table, MySQL locates the first UNIQUE index where all the key columns are NOT NULL and InnoDB uses it as the clustered index.

If the table has no PRIMARY KEY or suitable UNIQUE index, InnoDB internally generates a hidden clustered index named GEN_CLUST_INDEX on a synthetic column containing row ID values. The rows are ordered by the ID that InnoDB assigns to the rows in such a table. The row ID is a 6-byte field that increases monotonically as new rows are inserted. Thus, the rows ordered by the row ID are physically in insertion order.

如果定义了主键,那么InnoDB会使用主键作为聚集索引。为您创建的每个表定义一个主键。 如果没有逻辑唯一且非空的列或列集,请添加一个新的自动递增列,其值将自动填充。

如果没有定义主键,那么会使用第一非空的唯一索引(NOT NULL and UNIQUE INDEX)作为聚集索引

如果既没有主键也找不到合适的非空索引,那么InnoDB会自动生成一个不可见的名为ROW_ID的列名为GEN_CLUST_INDEX的聚簇索引,该列是一个6字节的自增数值,随着插入而自增

如果没定义主键,Mysql也会给你加上主键,而加的主键ROW_ID,其自增的实现来源于一个全局的序列,而所以有ROW_ID的表共享该序列,这也意味着插入的时候生成需要共享一个序列,那么高并发插入的时候为了保持唯一性就避免不了锁的竞争,进而影响性能

所以还是自己乖乖的加上主键吧

选什么字段作为主键呢?

表数据存储在B+Tree的叶子节点上,且按主键的顺序存放。因此每插入一条记录时,会根据其主键将其插入节点的适当位置。如果节点达到装载因子(InnoDB默认为15/16),则开辟一个新节点。

所以如果主键是自增的,则每次插入新的数据就会顺序添加到叶子节点上。这样就不需要移动叶子节点上的数据。效率更高,所占存储空间也更紧凑。

所以建议用自增字段作为主键

自增字段作为主键有没有缺点呢?

《高性能Mysql》:

对于高并发工作负载,在InnoDB中按主键顺序插入可能会造成明显的争用。主键的上届会变成“热点”。因为所有的插入都发生在这里,所以并发插入可能导致间隙锁竞争。另一个热点可能是AUTO_INCREMENT锁机制;如果遇到这个问题,则可能需要考虑重新设计表或者应用,或者更改innodb_autoinc_lock_mode配置。如果你的服务器版本还不支持innodb_autoinc_lock_mode参数,可以升级到新版本的InnoDB,可能对这种场景会工作得更好。

总结

对于InnoDB存储引擎,表一定要自己设定主键(你不设,mysql也会帮你设,而且还有隐患)

建议用自增的字段作为主键

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值