概述
分库分表后涉及到的另一个问题就是主键如何保证唯一且自增。以前单库单表的时候只需要利用数据库特性进行自增即可,现在因为是各自独立的库表,数据库之间的主键自增无法进行交互,比如数据库1的订单明细表主键自增到了1001,数据库2的订单明细表主键现在是1000,如果现在往数据库2的订单明细表中插入一条数据,这个时候获取到的主键ID会是1001,这样就会造成业务上的主键冲突。
全局ID
为了解决订单明细表主键的重复问题。靠数据库的主键自增是无法做到了。如何解决这个问题呢?可以给项目中引入一个全局唯一的ID服务,这个服务就是用来生成全局唯一ID的,每次生成的ID都不一样,可以保证主键的唯一性。
全局ID算法
全局ID需要保证如下的特性:
-
全局唯一:必须保证ID是全局性唯一的,基本要求
-
高性能:高可用低延时,ID生成响应要块,否则反倒会成为业务瓶颈
-
高可用:100%的可用性是骗人的,但是也要无限接近于100%的可用性
-
好接入:要秉着拿来即用的设计原则,在系统设计和实现上要尽可能的简单
-
趋势递增:最好趋势递增,这个要求就得看具体业务场景了,一般不严格要求
常用的全局ID算法如下:
- 雪花算法Snowflake
- 百度uid-generator
- 美团Leaf
- 滴滴Tinyid
雪花算法
雪花算法的结构:
主要分为 4 个部分:
- 是 1 个 bit:0,这个是无意义的。
- 是 41 个 bit:表示的是时间戳。
- 是 10 个 bit:表示的是机房 id,0000000000,因为我传进去的就是0。
- 是 12 个 bit:表示的序号,就是某个机房某台机器上这一毫秒内同时生成的 id 的序号,0000 0000 0000。
1 bit,是无意义的:
因为二进制里第一个 bit 为如果是 1,那么都是负数,但是我们生成的 id 都是正数ÿ