一,常见的下单途径
- Web网站下单
- 手机Wap下单
- 打电话到呼叫中心下单(少见)
如果采用常见的单数据库来存储的话,随着订单量的增加,单库的写压力增大,造成数据库服务器性能降低,一般会采用分库来缓解数据库服务器的压力,分库就分成不同的几个订单数据库,Web来源订单,存入Web订单库;手机Wap来源,存入Wap订单库等。最后再将这几种类型的数据库同步到订单主库中。在同步到订单主库的时候,首先电商网站一般用订单号来作为订单表的主键,因此,必须保证订单号的唯一性。
二,订单命名的几种规则
- 不重复:订单号的唯一性
- 安全性:订单编号中不能透露公司的任何信息,不要使用流水号,容易暴露公司的运营情况
- 不要使用大规模随机码:随机码可以保证订单号的安全性,但是当数据量比较大的时候,如果再生成新的订单,需要与之前数据的订单号进行比较,效率太低
- 防止并发:有时间的设定,防止并发,同一用户同一时间(精确到秒、毫秒)不会产生两个订单编码
- 控制位数:10-15位,有时间日期的可以方便客服,在用户投诉时,长的订单号报错几率高,影响效率
- 纯数字性,便于索引查询,文本型“字母+数字”不利于索引
淘宝的订单号规则:18位,前14位为序号,15-16位是用户ID倒数1-2位,17-18位是用户ID倒数3-4位
比较常见的几种订单号生成方法
一,使用UUID
UUID是一个128位长的数字,一般用16进制表示,算法的思想是结合机器的网卡、当地时间、一个随机数来生成GUID,从理论上讲,一台机器每秒产生1千万个GUID,可以保证3240年不重复。
优缺点:
二,使用数据库自增序列生成
利用数据库全局唯一。设置MySQL数据库自增起始值和步长,起始值不同,步长相等,则每个数据库生成的自增序列码可以避免相同。
优缺点:
三,推特雪花(snowflake)算法 (推荐)
推特公司的一款通过划分命名空间并行生成的算法,来解决全局唯一ID的需求。雪花算法,是64位二进制,转十进制,18位,第一位是符号位为0,第二阶梯的41位是毫秒,然后是5位datacenterId(最大支持2^5=32个,二进制表示从00000-11111,也即是十进制0-31),和5位workerId(最大支持2^5=32个,原理同datacenterId),所以datacenterId*workerId最多支持部署1024个节点,第四阶段最后12位每毫秒从0递增生产ID(12位的计数顺序号支持每个节点每毫秒产生4096个ID序列),那么一秒就是4096000,理论上每秒可以生成400万+,实际可能要低一点,大概300万左右。
四,基于Redis的自增
当使用数据库来生成ID性能不够要求时,我们可以尝试使用Redis来生成ID,这主要依赖于Redis单线程,所以可以生成全局唯一ID,使用Redis的INCR和INCRBY来实现。
可以使用Redis集群来获取更高的吞吐量。假如一个集群中有5台Redis,可以初始化1,2,3,4,5,然后步长为5,生成唯一ID。使用Redis集群还可以防止单点故障的问题。
优缺点:
五,全局订单号数据池
这个方法是个人的一个思考,没有实操过,欢迎指正。
尽量使用有意义的订单号,便利与客服和客户,比如说,这种生成规则:业务编码 + 时间戳 + 机器编号[前4位] + 随机4位数 + 毫秒数
业务编码就是哪一种订单数据库(Web、手机等),机器编号前4位(服务器的标识)。
每天的零点新生成一批订单号,然后放入Redis,走缓存,不要放入数据库,Redis使用List队列的先进先出,根据自己分公司的业务量设置一个容量,低于一半就添加,满了就停止,适用于并发量比较小的,这个可以不在并发量比较高的时候去大量生成,而是在空闲的时候成,直接存取Redis,效率还是比较高的。
本文参考:
https://blog.csdn.net/m0_37774696/article/details/85012554
https://blog.csdn.net/jiabeis/article/details/80999498
https://blog.csdn.net/li396864285/article/details/54668031
https://blog.csdn.net/qq_39597203/article/details/86504239
https://mp.weixin.qq.com/s/FJKHORl_PSaTrCPLrZ1ouQ