订单号和 id 列可不可以是同一列?

简介: 在分布式场景中,单表已经不能满足我们的需求了,所以用自增 id 的方案也就不合适了。当比如我们进行分表设计时,主键列到底如何生成就成了一个问题,流行的方法是利用像 snowflake 这样的算法计算出一个趋势有序的值作为 id。(当然还有其他多种方法)这样就满足了扩展性和一定程度上解决了检索性能的问题。

id 列


首先说 id 列一般作为主键,没有什么业务含义,设计的目的是为了查询和索引方便,如果用单表的情况下一般会设置为自增,有序了以后,无论数据库还是业务检索起来效率都非常高。


在分布式场景中,单表已经不能满足我们的需求了,所以用自增 id 的方案也就不合适了。当比如我们进行分表设计时,主键列到底如何生成就成了一个问题,流行的方法是利用像 snowflake 这样的算法计算出一个趋势有序的值作为 id。(当然还有其他多种方法)这样就满足了扩展性和一定程度上解决了检索性能的问题。


订单号


订单号的生成一般有相应的规则,而这些规则是各自产品根据自己情况自行设计的结果。


举几个例子


京东的:

  • 京东 2013 年的订单号 :479000238
  • 京东 2014 年的订单号 :7783813454
  • 京东 2018 年的订单号 :81467423041
  • 京东 2020 年的订单号 :132971864529


淘宝的:

  • 淘宝 2012 年的订单号 :230447522918072
  • 淘宝 2016 年的订单号 :2131062693288072
  • 淘宝 2019 年的订单号 :329062467847108072
  • 淘宝 2021 年的订单号 :2075316735066108072


可以看到京东和淘宝的订单号都是在递增的,而且淘宝的看起来是有规律的,这个查了一下有说从 2017 年淘宝升级了订单,原先是用订单号后 4 位识别用户,2017 年以后改为用后 6 位了。


“那么淘宝订单编号后 6 位用户 id 后 6 位的目的是什么?翻遍了百度、知乎,没有找到答案。我是偶然间翻到一份淘宝技术演变 PPT,看到订单表分库的逻辑时才恍然大悟。一般的平台型电商,订单量大,为保证查询检索速度,都会采用分库的形式,将巨量的订单信息分库存储,一般情况下订单系统同时维护了一个订单号和 userid 的关联关系,先根据订单号查到 userid,再根据 userid 确定分表进而查询得到内容。而淘宝在订单号上下功夫,通过订单号后 6 位直接锁定库表,大大提升高并发下的系统查询性能。从这个策略我们也可以看到淘宝用户订单库是按照用户 id 后 6 位存储的,例如:XXXX452154 格式的用户订单都是储存在一个分库中。


我通过查询发现自己的淘宝 id 后 6 位是 107280,而我的订单号后 6 位是 108072,还是有规律的。


找到了一个淘宝 2012 年的 PPT,可能 12 年之前的设计又不一样。


37.jpg


订单号生成规则


不重复显然,这种具有唯一标识的号码是不能重复的,安全不能被人为的猜测或推测出来,易识别易识别就代表位数不要太长,位数控制好了就容易查询检索,占用空间小。

几种常见的规则


  • 年月日+自增长数字的订单号(比如:2012040110235662)
  • 字母+数字字符串式,字母有包含特别意义,C02356652
  • Snowflake 算法生成
  • 年月日+机构编码+后四位随机


订单号可不可以作主键 id 列


前提是你根据你自己设计或选择的订单号规则生成了一个可行的订单号,这种情况下,如果你的订单号包含字母等字符串那么是不合适作主键的。虽然唯一,但索引查询性能较差。不过可以做唯一索引。


如果订单号是纯数字呢?


也不建议,数字当然有它的优点,性能好(位数长了也不好),但是订单号毕竟是跟业务相关的,与业务相关的列作主键本身可能会有问题。


假如未来的一天我们要改变业务含义,也许想把数字改字母,加几位或少几位,那么就必须修改主键了,核心数据表的主键修改,可是牵一发而动全身的,会造成极大的维护开销。


虽然直观上感觉“多了一列”,但并不是无用的,对未来的扩展性会有很大帮助。综上,回答我们标题的问题:“订单号和 id 列可不可以是同一列?” 或者说订单号可不可以作主键,我认为可以,但不适合,所以建议不要用订单号做主键。用与业务无关的 id 列作主键比较合适。


主键列怎么设置?


如果是单表,当然是用自增 id, 如果考虑到分库分表,可以采用像 snowflake 这样的生成方案。




相关文章
|
移动开发 前端开发 JavaScript
基于Vue的音乐播放器的设计与实现(论文+源码)_kaic
基于Vue的音乐播放器的设计与实现(论文+源码)_kaic
|
8月前
|
存储 算法 数据安全/隐私保护
密码如何存储?
本文介绍了密码存储的安全策略及加密算法对比。内容涵盖明文密码风险、彩虹表攻击原理,以及如何通过加盐、迭代哈希提升安全性,推荐使用 BCrypt 算法。同时比较了 DES、AES、SM4 对称加密算法,和 RSA、ECDSA、SM2 非对称加密算法的特性与应用场景。
378 0
EMQ
|
物联网 Linux C语言
在 Windows 平台搭建 MQTT 服务
NanoMQ 有着强大的跨平台和可兼容能力,不仅可以用于以 Linux 为基础的各类平台,也为 Windows 平台提供了 MQTT 服务的新选择。
EMQ
705 235
在 Windows 平台搭建 MQTT 服务
Python 绘制漂亮的折线图
折线图是一种用于展示数据随时间或其他变量变化趋势的图表。在 Python 中,我们可以使用`matplotlib`库来绘制漂亮的折线图。`matplotlib`是一个功能强大且广泛使用的绘图库,它提供了丰富的工具和选项来创建各种类型的图表。
Python 绘制漂亮的折线图
|
人工智能
西门子S7-300的硬件结构,各模块按照什么顺序来组态?
今天我们来介绍一下西门子S7-300的硬件结构,并和大家讲一下S7-300各模块是按照什么顺序来组态的。
西门子S7-300的硬件结构,各模块按照什么顺序来组态?
|
NoSQL 网络协议 Redis
Nomad 系列 -Nomad 网络模式
Nomad 系列 -Nomad 网络模式
|
监控 数据可视化 安全
如何查找访问 Nginx 的前 10 个 IP?
【5月更文挑战第1天】
873 1
如何查找访问 Nginx 的前 10 个 IP?
|
运维 安全 网络安全
自动化运维:使用Python脚本实现批量部署
【8月更文挑战第2天】在现代IT基础设施管理中,自动化运维成为提升效率、减少人为错误的关键。本文将通过一个实际的Python脚本示例,展示如何实现服务器的批量部署,包括环境准备、代码实现及执行过程。文章旨在为运维工程师提供一种简化日常任务的方法,同时强调安全性和可维护性的重要性。
|
消息中间件 存储 运维
深入理解MQ消息队列的高可用与可靠性策略
深入理解MQ消息队列的高可用与可靠性策略
1680 3
|
监控 网络协议 安全
【亮剑】当设备IP能ping通但无法上网时,可能是DNS解析、网关/路由设置、防火墙限制、网络配置错误或ISP问题
【4月更文挑战第30天】当设备IP能ping通但无法上网时,可能是DNS解析、网关/路由设置、防火墙限制、网络配置错误或ISP问题。解决步骤包括检查网络配置、DNS设置、网关路由、防火墙规则,以及联系ISP。预防措施包括定期备份配置、更新固件、监控网络性能和实施网络安全策略。通过排查和维护,可确保网络稳定和安全。
5998 1

热门文章

最新文章