不懂就问:如何正确设计一个订单号?

2021-04-15 09:37:00 +08:00
 sebastianwade

目前可能主要是考虑体量大了,查询索引优化问题。大牛们你们各家都是咋做的?

参考: 如何正确设计一个订单号???

5785 次点击
所在节点    程序员
22 条回复
hccsoul
2021-04-15 09:41:06 +08:00
我记得推特啥的好像有一个短一点的
liuhuan475
2021-04-15 09:59:14 +08:00
看看美团 leaf 取号器
xiaofenyi
2021-04-15 09:59:17 +08:00
生成订单号的函数如下:
function build_order_no(){
return date('Ymd').substr(implode(NULL, array_map('ord', str_split(substr(uniqid(), 7, 13), 1))), 0, 8);
}
shanghai1943
2021-04-15 10:00:06 +08:00
对外的订单号应该是纯数字的,方便用户查看和售后。
yitingbai
2021-04-15 10:02:38 +08:00
看业务需求, 订单号也不能纯粹的无意义啊, 比如我们做自动售货机的, 订单号上就要携带售货机编号,货道等数据
Veneris
2021-04-15 10:08:54 +08:00
订单号应至少满足以下需求:
1.纯数字,或者字母只做前缀用,方便售后等,
2.自增,
3.非连续,反正竞争对手间隔一定时间下单,根据订单号推送平台订单量,
4.高并发
5. ...
综上,推荐推特的雪花算法,或者以此为基础的美团百度变种。
labulaka521
2021-04-15 10:23:55 +08:00
github.com/sony/sonyflake 比推特的可用时间长
The lifetime (174 years) is longer than that of Snowflake (69 years)
acthtml
2021-04-15 10:27:42 +08:00
不推荐自增型的,因为对手能知道你的体量。
Jooooooooo
2021-04-15 10:28:23 +08:00
雪花比较好

一天生成好几千万的单号没问题
clf
2021-04-15 10:40:01 +08:00
看你的订单号要不要有具体的意义,比如说,年-月-日-时-分-秒-结算柜台编号,就可以简单的保证 ID 不重复,且随着时间增加。(同时不可能在一个柜台产生两个订单)

如果不需要特别的意义,只需要是唯一 ID,那么雪花算法挺好的,正常情况下也不会改服务器时间。查询效率和数据库自增差距不大。

只要存储类型是数字,且有一定的增长趋势,那么查询效率都还可以的。别往里面丢字符就行。
no1xsyzy
2021-04-15 10:41:21 +08:00
内部订单号不应以任何方式对外(包括最终用户和非运维的操作员)暴露,而仅仅用于系统内部,唯程序和调试时可读,如此一来可以使外部订单号的设计较为宽松,且任何时间可以修改(还不会像 BV 号那样秒破译)

内部订单号需要:数字格式的纯数字,方便索引和传输;生成过程高并发
外部订单号需要:尽可能提供责任归属信息,方便任务分发;没有歧义字符(无论声、光);生成过程高并发;难以遍历;最好带校验位提供冗余信息

显然,前者本机 ID+自增 ID 完全可以承载,或者雪花;后者依赖具体情况,典型是身份证号码,每段含义明确,不是纯数字也没有关系,无论是读出来还是写出来,X 都不会造成歧义,并且最后一位是校验位提供了冗余信息错误的身份证号码可以被离线检测出来。
seanxx
2021-04-15 11:18:15 +08:00
@acthtml #8 那只能适应于订单号不需要索引的场景
realpg
2021-04-15 11:54:37 +08:00
顺序生成数字,考虑分布式就多服务器间隔顺序生成

然后做一个显示变换,在显示给用户和用户传入到后台进行一次 encode/decode
abersheeran
2021-04-15 13:28:53 +08:00
@no1xsyzy 好想法!学到了。有一个问题,“没有歧义字符(无论声、光)” 是指什么? 0oO ilIL 这种?
VeryZero
2021-04-15 13:32:32 +08:00
雪花算法有优化版,可以解决过长和时间回调的问题
no1xsyzy
2021-04-15 14:58:33 +08:00
@abersheeran 差不多,具体得看你对歧义有多大忍耐程度
像无线电,017 都要特殊读音(洞、幺、拐),还有北约音标字母
最好还要 OCR 友好,这方面可能需要字体的帮助。
——
顺便好像校验位还有个好处,如果上手直接尝试遍历的,很快会因为校验位不正确被发现。如果校验位不正确请求比例很高,则可以很快地发现遍历者,甚至在流量实际接触到数据库之前就能被防下来。意外的好处,虽然实际用途不大(
WishMeLz
2021-04-15 17:31:58 +08:00
我想起来我之前设计的订单号 公司首字母+年月日+后六位时间戳+4 位随机字母。 哈哈哈,真的简单
akira
2021-04-15 20:59:04 +08:00
自增 id 不要参与业务
xuanbg
2021-04-15 21:44:18 +08:00
我做了个自定义单号生成器,用户可以自定义规则来生成任何他想要的编号。想顺序就顺序,想乱序就乱序,绝不会重复。
Rocketer
2021-04-15 22:43:26 +08:00
还有个方案是做个订单号服务,提前生成好再分配,很多短网址是这么做的

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/770751

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX