为什么要用自增主键?

拥抱变化

关于这个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可以用来做分页优化。当然这是另一个话题了,下次分析。
本站所有文章均来自互联网,如有侵权,请联系站长删除。极客文库 » 为什么要用自增主键?
分享到:
赞(0)

评论抢沙发

评论前必须登录!