前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >为什么要用自增主键?

为什么要用自增主键?

作者头像
Leetcode名企之路
发布2019-07-14 13:45:30
4.2K0
发布2019-07-14 13:45:30
举报
文章被收录于专栏:Leetcode名企之路Leetcode名企之路

拥抱变化

关于这个topic,在网上搜索出来的,很多你可以看到这么一句话:

在设计数据库时不需要费尽心思去考虑设置哪个字段为主键。

这固然没错,但是不那么具有说服力。最近在做商业账号的项目的时候,对这点体会尤为深刻。我觉得设置自增主键的最主要目的是:应对变化

笔者遇到的场景为:维护商业账号的资质相关信息。账号是由全局唯一且自增的分布式ID生成器生成的,很显然这个时候我们把账号作为主键这就天然合理。于是,初版建表的时候就有了如下表结构:

代码语言:javascript
复制
accountId // 主键, 账号ID,全局唯一
cert // 该账号的资质
review_detail // 该账号的审核详情
cert_photo // 资质的图片
...

当时业务迭代一定时间之后,新的需求来了:一个账号,在不同业务线,需要享有不同资质。

代码语言:javascript
复制
accountId // 主键, 账号ID,全局唯一
business // 新加入的字段,标志不同业务线.
cert // 该账号的资质
review_detail // 该账号的审核详情
cert_photo // 资质的图片
...

这个时候就accountId就不是一个唯一的了,因为,同一个账号,不同业务线,资质是不一样的。

笔者和同事讨论之后,做出如下方案:

  1. 先把原来业务代码中依赖主键查询的代码做升级;
  2. 把数据库原来的索引drop掉;
  3. 新建自增主键索引;
  4. 升级当前业务,实现同一账号,不同系统,享有不同资质;

但是第二步之后,实际上drop掉主键,这个时候Mysql是没有主键状态的。如果没有定义主键,则会使用非空的UNIQUE键做主键 ; 如果没有非空的UNIQUE键,则系统生成一个6字节的rowid做主键

这么做其实可能会有性能问题。

如果我们一开始设计表的时候,就用业务无关的ID作为自增主键,那么本次升级就不会变得这么麻烦。推荐的做法是,在系统设计之初:

  1. 设置自增主键;
  2. 把当前需要约束的键(这里即账号ID)作为唯一键约束;

主键: 1.可以定义一列或多列为主键。不允许空(NULL),主健可作外健,唯一索引不可; 2.定义一个主键将自动创建主键索引,主键索引是唯一索引的特殊类型。 唯一键: 1.唯一性约束用来限制不受主键约束的列上的数据的唯一性,用于作为访问某行的可选手段, 指定列上都不允许有相同的值,允许空(NULL) 2.唯一约束可以用于保证在基表中增加一条记录时,一个或多个列值是唯一的。

性能考量

  1. 如果表使用自增主键,那么每次插入新的记录,记录就会顺序添加到当前索引节点的后续位置,当一页写满,就会自动开辟一个新的页。如果不是自增主键,那么可能会在中间插入,学过数据结构的同学都知道,在中间插入,B+树为了维持平衡,引起B+树的节点分裂。总的来说用自增主键是可以提高查询和插入的性能。
  2. 在切换这段时间,如果你的系统对latency非常敏感,那么就不能这么简单的做了,可能需要重新备份数据库,由于笔者维护这个表是B端系统,且数据量级大概百万量级,这么搞是OK的。
  3. 自增ID可以用来做分页优化。当然这是另一个话题了,下次分析。
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-07-10,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Leetcode名企之路 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 拥抱变化
  • 性能考量
相关产品与服务
访问管理
访问管理(Cloud Access Management,CAM)可以帮助您安全、便捷地管理对腾讯云服务和资源的访问。您可以使用CAM创建子用户、用户组和角色,并通过策略控制其访问范围。CAM支持用户和角色SSO能力,您可以根据具体管理场景针对性设置企业内用户和腾讯云的互通能力。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档