基于时间戳的订单号生成规则思考

 

订单号看似不起眼的一个东西,可它作为一种交易凭据,事实上是电商系统比较重要的一个东西。一个比较理想的订单号要满足以下几点

  • 唯一性

    每个订单号对应一笔订单交易

  • 可读性

    使用订单号的场景通常是用户反馈异常订单给客服,太长、太复杂的单号容易误报,增加客服工作量。

  • 安全性

    订单号不能直接体现单量,否则销量就会被轻易读取。

下面来探讨一下可能会被使用的几种单号生成策略。

订单号生成规则

UUID

UUID可以生成一串32位字符唯一的字符串,如下:

90b4c292-99ec-41f1-a615-783c9a9226aa

直接使用UUID作为单号,唯一、安全,不过没有可读性可言。这种不适合一般的电商系统,可以用在线下的点餐系统。如麦当劳之类的,除了单号还会有个临时的取餐号,可以作为一种短暂的凭据。

Unix时间戳

Unix时间戳可以提供10位字符长度数字,通常这也是一种解决方案,如果系统单量不是很大,也可以采用。比较致命的问题时当单量很大,很容易出现重复的单号(同一秒)。

unix_timestamp + random

解决上面的问题可以通过增加一定长度的随机数。同样,这种方式只适合一些单量很小的系统。

混合的时间

Unix时间戳缺点很多。一来无法满足唯一性,二来可读性很差。不过混合时间是很多电商系统常用的一种方式。具体策略如下:

年后两位 + 月 + 日 + 秒 + 自增序列

举例: 19-01-10-14321-0001,下面来逐个讲解一下各部分。

  1. 年月日

    这个不用多讲,

  2. 我们用秒来替换时、分、秒,因为一天最多就86400秒,从秒可以逆推出当天的时分秒。

  3. 自增序列

    自增序列通常使用3-5位,4位表示1秒最多允许出现1万个订单,达到最大值重新累计。

基于时间戳的订单号就是取当前的时间作为基本的信息,在此基础上往时间戳前、后分别加上一些业务相关的字符,组成一个订单号。比如:

下单渠道 + time_base_str + (你想要的业务信息)

小米的单号其实就是这种方式,可以观察其他的电商系统,挺多都是基于时间。这种方式一定程度上满足上面提到的几点要素。

优化长度

上面的单号其实还是有点长,事实上月和日还有进一步优化的空间。因为一年最多只有366天,我们可以算出下单时是一年中的第几天,就可以减少一位长度。

19-100-14321-0001

上面表示的是2019年的第100天,14321秒的第2个单。牺牲了一点可读性减少了一位长度,是否值得就看大伙儿的需求是否允许了。

结尾

基于混合时间的单号是一种比较理想的单号,我们公司现在就是采用这种方式。当然不完全是这样,至于策略的细节就不能公开了。这里仅仅是抛砖引玉,有更好办法的我们不妨一起探讨一下。