方案一 :独立数据库自增id
系统每次要生成一个id,都是往独立库的一个独立表里面插入一条数据,获取自增的id。再拿着这个id去往对应的分库分表里面去写
优缺点:
简单好用,但是高并发有瓶颈,单个库每秒承载好几万的并发也是不现实的
方案二 :uuid
好处就是本地系统生成,
缺点:uuid太长了,作为主键性能太差。 而且是无序的,innodb索引页分裂,影响性能
方案三:获取当前系统时间
这个方案的意思就是获取当前时间作为全局唯一的id。但是问题是,并发很高的时候,比如一秒并发几千,会有重复的情况,这个是肯定不合适的。
一般如果用这个方案,是将当前时间跟很多其他的业务字段拼接起来,作为一个id,比如说订单编号:时间戳 + 用户id + 业务含义编码。
方案四:snowflake算法
snowflake算法,是twitter开源的分布式id生成算法。
其核心思想就是:使用一个64 bit的long型的数字作为全局唯一id,这64个bit中,其中1个bit是不用的,然后用其中的41 bit作为毫秒数,用10 bit作为工作机器id,12 bit作为序列号。
上面第一个部分,是1个bit:0,这个是无意义的。
上面第二个部分是41个bit:表示的是时间戳。
上面第三个部分是5个bit:表示的是机房id,10001。
上面第四个部分是5个bit:表示的是机器id,1 1001。
上面第五个部分是12个bit:表示的序号,就是某个机房某台机器上这一毫秒内同时生成的id的序号,0000 00000000
snowflake算法一个小小的改进思路
其实在实际的开发中,这个snowflake算法可以做一点点改进。
因为大家可以考虑一下,我们在生成唯一id的时候,一般都需要指定一个表名,比如说订单表的唯一id。
所以上面那64个bit中,代表机房的那5个bit,可以使用业务表名称来替代,比如用00001代表的是订单表。
因为其实很多时候,机房并没有那么多,所以那5个bit用做机房id可能意义不是太大。
这样就可以做到,snowflake算法系统的每一台机器,对一个业务表,在某一毫秒内,可以生成一个唯一的id,一毫秒内生成很多id,用最后12个bit来区分序号对待。