主键的选择
非聚集索引
自增ID节省空间,UUID相对浪费空间
堆表索引
无所谓用哪种
自增ID vs UUID
自增ID | UUID | |
---|---|---|
优点 | - 递增,聚集索引性能更好 -节省空间 | - 全局唯一 - 更加安全 |
缺点 | - 不利迁移 - 不利扩展 | - 无序,聚集索引页分裂 - 相对浪费空间 |
推荐方案
- 对于单库应用,聚集索引(MySQL)强烈推荐自增ID,堆表(Oracle)推荐使用自增ID,也可以考虑UUID。
- 对于分库分表,推荐使用全局唯一、趋势递增的分布式ID。
分布式ID
UUID
单机数据库自增ID(专门用一个数据库生成自增id,所有数据库用这个数据的的id)
Redis自增ID(性能比单机数据库更强)
跳跃式自增ID
Db1: 1,3,5,7 ...
Db2: 2,4,6,8 ...
Snowflake及其改进算法
使用 8 字节码 64 bit
1bit :保留位
41bit:时间戳;精确到毫秒,可用 69 年
10bit:机器 id;容纳 1024 节点
12bit:序列号;递增 4096 个
一毫秒内最多生成 1024 * 4096 = 4194304 个 ID
如果服务器时间走快了生成id,有可能在服务器时间正常后发生碰撞
思考题
能不能用业务字段,比如身份证号或者手机号,作为主键?
不推荐使用业务字段作为主键,主键的选取要保证业务无关性,原因有两点:
- 会对信息的安全性造成影响,其它表引用主键会泄漏信息
- 如果业务字段发生修改,那么主键修改,其它表如果有引用数据完整性被破坏
主键必须是单独的,完全没有业务含义的字段,也就是主键本身除了唯一标识和不可修改这两个责任外,主键没有任何业务含义。
推荐文章
廖雪峰 浅谈数据库主键策略