1.利用全球唯一UUID生成订单号
UUID优缺点
优点:
简单,代码方便
生成ID性能非常好,基本不会有性能问题
全球唯一,在遇见数据迁移,系统数据合并,或者数据库变更情况下,可以从容应对
缺点:
没有排序,无法保证趋势递增
UUID往往是使用字符串存储,查询效率比较低
存储空间比较大,如果是海量数据库,就需要考虑存储量的问题
传输数据量大
2.利用数据库自增
数据库集群的话,如何解决自增id唯一问题
答案:设置步长,每台节点自增步长不同
步长:在自增当中,增长的数量,默认自增1
但是扩展性不好
查询自增步长(SHOW VARIABLES LIKE ‘auto_incr%’;)
修改自增步长(SET @@auto)increment_increment=10;)
修改起始值(SET @@auto_increment_offset=5;)
注意:在最开始设置好了每台节点自增方式步长后,确定好了mysql集群数量后,无法扩展新的mysql,不然生成步长的规则会被打乱
3. 基于redis生成全局id策略
因为redis是单线程的,天生保证原子性,可以使用redis的原子操作 INCR
优点:
不依赖数据库,灵活方便,且性能优于数据库
数字ID天然排序,对分页或者需要排序的结果很有帮助
缺点:
需要编码和配置的工作量比较大
注意:在redis集群情况下,同样和redis一样需要设置不同的增长步长,同时key一定要设置有效期
public static String prefix() {
String temp_str = "";
Date dt = new Date();
// 最后的aa表示“上午”或“下午” HH表示24小时制 如果换成hh表示12小时制
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
temp_str = sdf.format(dt);
return temp_str;
}
@RequestMapping("/order")
public String order(String key) {
RedisAtomicLong redisAtomicLong = new RedisAtomicLong(key, redisTemplate.getConnectionFactory());
long andIncrement = redisAtomicLong.getAndIncrement();
String orderId = prefix() + "-" + String.format("%1$05d", andIncrement);
return orderId;
}