1.利用全球唯一UUID生成订单号
UUID是一个字符串而且没有顺序,所以不适合做主键,可以 做 token 使用。
利用全球唯一UUID生成订单号 UUID基本概念: UUID是指在一台机器上生成的数字,它保证对在同一时空中的所有机器都是唯一的。
UUID组成部分:当前日期和时间+时钟序列+随机数+全局唯一的IEEE机器识别号 全局唯一的IEEE机器识别号:如果有网卡,从网卡MAC地址获得,没有网卡以其他方式获得。
优点: 简单,代码方便 生成ID性能非常好,基本不会有性能问题 全球唯一,在遇见数据迁移,系统数据合并,或者数据库变更等情况下,可以从容应对
缺点: 没有排序,无法保证趋势递增 UUID往往是使用字符串存储,查询的效率比较低 存储空间比较大,如果是海量数据库,就需要考虑存储量的问题。 传输数据量大
一般UUID在生成Token领域使用比较多
2.利用数据库自增
如果使用数据库id自增生成订单号的话,如果数据库是集群的话 则有可能生成相同的订单号。
所以如果我们使用数据库id 自增做为全局 id 的话我们需要设置步长,步长表示每次自动增长的数量。
举栗子:
假如现在有 3 台 MySql 数据库做集群,mysql1,mysql2,mysql3。
设置mysql1数据库id初始值为0,mysql数据库id初始值为1,mysql3数据库id初始值为2。我们这时候需要设置步长为3,
mysql1每次自增结果为 0,3,6,9,12,15
mysql2每次自动结果为 1,4,7,10,13,16
mysql3每次自动结果为 2,5,8,11,14,17
........
这就是最后产生自增的结果,但是这种方法还有一个缺点,就是如果后期增加数据库服务器集群数量的话,mysql 步长无法扩展。所以使用这种方法生成全局id,需要前期确定好mysql数据库集群的数量,不然那到后期扩展集群数量会导致生成步长规则发生改变,可能会产生重复的id。
在数据库集群环境下,默认自增方式存在问题,因为都是从1开始自增,可能会存在重复,应该设置每台节点自增步长不同。
查询自增的步长
SHOW VARIABLES LIKE 'auto_increment%'
修改自增的步长
SET @@auto_increment_increment=10;
修改起始值
SET @@auto_increment_offset=5;
3. 基于redis生成全局id策略
因为Redis是单线的,天生保证原子性,可以使用Redis的原子操作 INCR和INCRBY来实现
优点: 不依赖于数据库,灵活方便,且性能优于数据库。 数字ID天然排序,对分页或者需要排序的结果很有帮助。
缺点: 如果系统中没有Redis,还需要引入新的组件,增加系统复杂度。 需要编码和配置的工作量比较大。
注意:在Redis集群情况下,同样和Redis一样需要设置不同的增长步长,同时key一定要设置有效期 可以使用Redis集群来获取更高的吞吐量。
假如一个集群中有5台Redis。可以初始化每台Redis的值分别是1,2,3,4,5,然后步长都是5。
各个Redis生成的ID为:
A:1,6,11,16,21
B:2,7,12,17,22</