专栏首页Leetcode名企之路为什么要用自增主键?

为什么要用自增主键?

拥抱变化

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

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

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

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

accountId // 主键, 账号ID,全局唯一
cert // 该账号的资质
review_detail // 该账号的审核详情
cert_photo // 资质的图片
...

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

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可以用来做分页优化。当然这是另一个话题了,下次分析。

本文分享自微信公众号 - Leetcode名企之路(DailyLeetCode)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-07-10

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 2019年中国软件行业基准数据在京发布

      权威的软件行业基准数据,是支撑软件造价评估系列国家标准、行业标准和地方标准落地应用的必要保障和支撑。北京软件造价评估技术创新联盟与中国电子技术标准化研究院、...

    软件造价评估联盟
  • 缓存雪崩 & 缓存穿透

    一个会写诗的程序员
  • 3.shell编程-文件查找之find命令

    搜索/home/shell_learn/下的文件,文件名以.sh结尾,且修改时间在一个星期之内的,然后将其删除

    zhang_derek
  • Puzzle 18 - StringCheese - byte storage

    Jerry Wang
  • 高性能服务器架构思路(一)——缓冲策略

    在服务器端程序开发领域,性能问题一直是备受关注的重点。业界有大量的框架、组件、类库都是以性能为卖点而广为人知。然而,服务器端程序在性能问题上应该有何种基本思路,...

    凯哥Java
  • 深度剖析MySQL慢更新问题

    根据运维同学反馈,数据库是不定期出现慢查询的现象,怀疑数据库可能存在死锁问题。由于问题复现的不确定性,因此在线上实例写脚本抓现场:当问题出现时,记录下innod...

    腾讯数据库技术
  • 1.django restframework 项目部署到ubuntu18.04上(同步数据库)

    选择本地要传输到服务器的数据库,然后选择数据库连接,点击开始,确定,然后等待传输完成,关闭。

    玩蛇的胖纸
  • GenerationType, JPA提供的四种标准用法为TABLE,SEQUENCE,IDENTITY,AUTO.

    GenerationType, JPA提供的四种标准用法为: TABLE,SEQUENCE,IDENTITY,AUTO.

    一个会写诗的程序员
  • 关于web系统整体优化提速总结

      随着公司业务的拓展,随之而来就是各种系统横向和纵向的增加,PV、UV也都随之增加,原有的系统架构和模式慢慢遇上了瓶颈,需要逐步的对系统从整体上进行改造升级,...

    小小许
  • optimistic locking failed; nested exception is org.hibernate.StaleObjectStateException: Row was u...

    optimistic locking failed; nested exception is org.hibernate.StaleObjectStateExc...

    一个会写诗的程序员

扫码关注云+社区

领取腾讯云代金券