主键的选择

非聚集索引

自增ID节省空间,UUID相对浪费空间

堆表索引

无所谓用哪种

自增ID vs UUID

自增IDUUID
优点- 递增,聚集索引性能更好
-节省空间
- 全局唯一
- 更加安全
缺点- 不利迁移
- 不利扩展
- 无序,聚集索引页分裂
- 相对浪费空间

推荐方案

  • 对于单库应用,聚集索引(MySQL)强烈推荐自增ID,堆表(Oracle)推荐使用自增ID,也可以考虑UUID。
  • 对于分库分表,推荐使用全局唯一、趋势递增的分布式ID。

分布式ID

  1. UUID

  2. 单机数据库自增ID(专门用一个数据库生成自增id,所有数据库用这个数据的的id)

  3. Redis自增ID(性能比单机数据库更强)

  4. 跳跃式自增ID

    Db1: 1,3,5,7 ...

    Db2: 2,4,6,8 ...

  5. Snowflake及其改进算法

    使用 8 字节码 64 bit

    1bit :保留位

    41bit:时间戳;精确到毫秒,可用 69 年

    10bit:机器 id;容纳 1024 节点

    12bit:序列号;递增 4096 个

    一毫秒内最多生成 1024 * 4096 = 4194304 个 ID

    如果服务器时间走快了生成id,有可能在服务器时间正常后发生碰撞

思考题

能不能用业务字段,比如身份证号或者手机号,作为主键?

不推荐使用业务字段作为主键,主键的选取要保证业务无关性,原因有两点:

  1. 会对信息的安全性造成影响,其它表引用主键会泄漏信息
  2. 如果业务字段发生修改,那么主键修改,其它表如果有引用数据完整性被破坏

主键必须是单独的,完全没有业务含义的字段,也就是主键本身除了唯一标识和不可修改这两个责任外,主键没有任何业务含义。

推荐文章

廖雪峰 浅谈数据库主键策略open in new window