看到好的东西要记下来。
首先,对于这个题目要满足: 1、唯一性 2、递增性(有利于数据库索引性能) 3、高可用(要利于分库分表) 4、无规律(安全)
方案一:数据库自增
实现要点:行锁 优势:
代码语言:javascript复制简单,利用数据库自有功能实现。
绝对有序。
缺点:
代码语言:javascript复制有重复发号的风险,例如数据库主从切换的场景。
需要特别保障其高可用。
发号性能限制于数据库性能,如需提高发号能力,需要扩充数据库,成本高。
方案二:Redis自增
Redis 提供了自增的原子命令,可以保证唯一、有序。
优点:
代码语言:javascript复制简单,自有能力。
高并发环境下性能好,优于数据库。
维护成本低于数据库。
缺点:
代码语言:javascript复制主从切换时也可能会重复发号。
需要特别保障其高可用。
方案三:雪花算法
给每台机器分配一个唯一标识,然后通过下面的结构实现全局唯一ID:
时间戳 机器标识 自增序列号
毫秒在高位,自增序列在低位,一定是递增的。
优点:
代码语言:javascript复制生成性能高。
灵活,可以根据自身业务特点分配bit位。
缺点:
代码语言:javascript复制强依赖机器时钟,如果时钟回拨,就会导致服务异常。
方案四:据说是某宝的方案
代码语言:javascript复制时间戳 类用户ID 递增的数值
代码语言:javascript复制唯一性:这种方案的订单号只有在同一个用户在同一毫秒内下多个订单才会出现出现,很显然,对于正常的用户行为,是不可能出现重复的,所以满足唯一性。
高并发:这个设计方案完全不依赖任何第三方服务,只通过一定的规则就能生成。所以这种方案不但高并发,而且零消耗。
递增性:因为订单号的前一部分是时间戳,所以满足趋势递增。并且,也满足非绝对递增的特性。
分库分表:假设分库分表因子为订单号中的类用户ID,那么无论是根据订单ID查询,还是根据用户ID查询,都不会涉及跨库跨表,效率非常高。
这里的类用户ID 指对ID进行处理,如哈希处理等。
案例学习
雪花算法 采用redis的解决方案 还是雪花算法