关于这个topic,在网上搜索出来的,很多你可以看到这么一句话:
在设计数据库时不需要费尽心思去考虑设置哪个字段为主键。
这固然没错,但是不那么具有说服力。最近在做商业账号的项目的时候,对这点体会尤为深刻。我觉得设置自增主键的最主要目的是:应对变化。
笔者遇到的场景为:维护商业账号的资质相关信息。账号是由全局唯一且自增的分布式ID生成器生成的,很显然这个时候我们把账号作为主键这就天然合理。于是,初版建表的时候就有了如下表结构:
accountId // 主键, 账号ID,全局唯一
cert // 该账号的资质
review_detail // 该账号的审核详情
cert_photo // 资质的图片
...
当时业务迭代一定时间之后,新的需求来了:一个账号,在不同业务线,需要享有不同资质。
accountId // 主键, 账号ID,全局唯一
business // 新加入的字段,标志不同业务线.
cert // 该账号的资质
review_detail // 该账号的审核详情
cert_photo // 资质的图片
...
这个时候就accountId就不是一个唯一的了,因为,同一个账号,不同业务线,资质是不一样的。
笔者和同事讨论之后,做出如下方案:
但是第二步之后,实际上drop掉主键,这个时候Mysql是没有主键状态的。如果没有定义主键,则会使用非空的UNIQUE键做主键 ; 如果没有非空的UNIQUE键,则系统生成一个6字节的rowid做主键
这么做其实可能会有性能问题。
如果我们一开始设计表的时候,就用业务无关的ID作为自增主键,那么本次升级就不会变得这么麻烦。推荐的做法是,在系统设计之初:
主键: 1.可以定义一列或多列为主键。不允许空(NULL),主健可作外健,唯一索引不可; 2.定义一个主键将自动创建主键索引,主键索引是唯一索引的特殊类型。 唯一键: 1.唯一性约束用来限制不受主键约束的列上的数据的唯一性,用于作为访问某行的可选手段, 指定列上都不允许有相同的值,允许空(NULL) 2.唯一约束可以用于保证在基表中增加一条记录时,一个或多个列值是唯一的。