专栏首页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 条评论
登录 后参与评论

相关文章

  • 【Leetcode】137.只出现一次的数字 II

    给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现了三次。找出那个只出现了一次的元素。

    Leetcode名企之路
  • 【Leetcode】124. 二叉树中的最大路径和

    本题中,路径被定义为一条从树中任意节点出发,达到任意节点的序列。该路径至少包含一个节点,且不一定经过根节点。

    Leetcode名企之路
  • 【Leetcode】62. 不同路径

    一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为“Start” )。

    Leetcode名企之路
  • 浅谈数据库主键策略

    浅谈数据库主键策略 数据库表的主键很多童鞋都非常熟悉了,主键就是Primary Key,简称PK。 数据库主键的作用是唯一标识一条记录,所以在同一张表中,...

    用户1212940
  • MySQL的主键详解

    一列 (或一组列),其值能够唯一区分表中的每个行。唯一标识表中每行的这个列(或这组列)称为主键。主键用来表示一个特定的行。没有主键,更新或删除表中特定行很困难,...

    JavaEdge
  • 数据结构(ER数据库)设计规范 原

    表命名的规则分为3个层级,层级之间通过_分割,例如b_r_identity、d_l_identity。规约为:

    随风溜达的向日葵
  • MySQL 之主键

    小编在查询相关的学习资料的同时,偶尔会遇到关于主键的信息,也是一直没有很清晰的认知,所以,这篇学习笔记,主要是和大家一起分享有关主键的知识。

    DataScience
  • 大战MySQL主键及其操作

    《原则》原文:但我不敢确信这场转型会顺利,因为我没有经历过这样的事情。我做事的方式是试错:犯错,找出错误原因,总结出新的原则,最终成功。而我觉得应该以同样的态度...

    小Bob来啦
  • 向mysql数据库中插入数据时显示“Duplicate entry '1′ for key ‘PRIMARY' ”错误

    错误情况如题,出现这个错误的原因十分简单: 很明显,这是主键的问题。 在一张数据表中是不能同时出现多个相同主键的数据的 这就是错误的原因,解决的方法...

    roobtyan
  • SQL反模式学习笔记22 伪键洁癖,整理数据

    在插入新行时,通过遍历表,找到的第一个未分配的主键编号分配给新行,来代替原来自动分配的伪主键机制。

    张传宁老师

扫码关注云+社区

领取腾讯云代金券