订单编号生成规则

订单号生成是系统设计中常见的问题,特别是在分布式系统中,生成唯一性高效性的订单号是非常重要的。

(1)自增数字序列

使用数据库的自增主键、redis的INCR 命令生成序列化。

例如,订单号可以是"202310280001",其中"20231028"表示日期,"0001"是自增的订单序号。

(2)时间戳+随机数

将年月日时分秒和一定范围内的随机数组合起来。有重复的风险。

例如,订单号可以是"20181028124523" + "1234",其中"20181028124523"表示日期和时间,"1234"是随机生成的数字。

(3)订单类型+日期+序号

将订单类型(例如"01"表示普通订单,"02"表示VIP订单等)、日期和序号组合起来。加上订单类型的好处是方便客户服务,根据订单号就可以知道订单的类型。

例如,订单号可以是"0101028100001",其中"01"表示订单类型,"20181028"表示日期,"00001"是序号。

(4)分布式唯一ID生成器

使用分布式唯一ID生成器(例如Snowflake算法)生成全局唯一的ID作为订单号。Snowflake 算法根据机器ID、时间戳、序号等因素生成,保证全局唯一性,它的优势在于生成的 ID 具有趋势递增、唯一性、高效性等特点.

Snowflake 算法对系统时钟的依赖性较强,如果系统时钟发生回拨,可能会导致 ID 生成出现问题。因此,在使用 Snowflake 算法时,需要定时进行时钟同步,确保系统时钟的稳定性。

1. 为什么需要订单编号

订单表已经有一个唯一的订单id了,为什么还需要一个唯一的订单编号呢?订单id已经可以唯一标识一个订单。

在订单表中,订单ID订单编号 都可以唯一标识一个订单,但它们存在的意义和用途有所不同,因此在实际开发中通常会同时存在这两个字段。以下是常见的原因:

1.1 技术层面 vs 业务层面

  • 订单ID:通常是数据库的主键,用于技术层面上的唯一标识,常常是自增的整数类型或者使用如 Snowflake 算法生成的唯一ID。它是系统内部用于快速查询和关联数据的标识符,不对用户显示,也不用于业务流程。
  • 订单编号:则是面向业务的唯一标识,用于在外部系统、用户、客服人员之间传递和沟通。它通常遵循一定的业务逻辑,如包含时间戳、业务类型、随机数等信息。

1.2 可读性

  • 订单ID 一般是技术生成的长整型数字或类似的随机字符串,缺乏人类可读性,不适合客户或运营人员使用。
  • 订单编号 则可以根据业务需求进行定制,如时间戳、订单类型等信息,使其更具可读性。

1.3 防止泄漏系统内部逻辑

  • 订单ID 有时是数据库自增主键,暴露给用户或外部系统可能导致系统的设计逻辑泄漏,甚至可能引发安全问题(如通过观察ID的自增模式进行攻击)。
  • 订单编号 可以通过自定义的生成规则,使外部无法猜测出系统内部的逻辑和订单的具体数量,增加系统安全性。

1.4 不同系统间的关联

在一个复杂的业务系统中,订单号可能需要与其他子系统(例如物流、支付、CRM系统)进行对接。为了更好地在不同系统之间传递和识别订单,通常会设计一个业务层面的订单编号,这样能够确保订单在跨系统操作时的唯一性和一致性。

1.5 排错与客服支持

在进行客服支持时,使用自增的 订单ID 进行沟通不太直观,而订单编号可以包含更多业务信息(如日期、订单类型等),更有助于客服人员快速定位订单,且便于客户理解和记忆。

2. 订单编号生成规则

2.1 自增数字序列

2.1.1 实现方式

  • 通过数据库的自增主键来生成订单号。
  • 使用 Redis 的 INCR 命令来生成唯一的自增序列。

2.1.2 优点

  • 简单易用:实现逻辑简单,依赖于数据库或 Redis 的自增特性。
  • 订单号有序:生成的订单号按顺序递增,易于排序和管理。

2.1.3 缺点

  • 单点瓶颈:如果依赖数据库的自增主键,数据库成为单点瓶颈,可能无法应对高并发场景。
  • 不适用于分布式:在分布式系统中,由于多台服务器并发处理,依赖单个数据库或 Redis 节点来生成自增序列可能导致性能瓶颈或冲突。

2.1.4 使用场景

  • 适用于小型项目或单一服务系统,订单量不大且没有分布式需求的场景。

2.2 时间戳 + 随机数

2.2.1 实现方式

  • 当前时间戳(如年月日时分秒)与一定范围内的随机数组合,生成订单号。

2.2.2 优点

  • 实现简单:生成逻辑易于实现,不需要依赖外部系统。
  • 包含时间信息:通过时间戳可以轻松获取订单的生成时间。

2.2.3 缺点

  • 重复风险:由于随机数范围有限,存在生成重复订单号的风险,特别是在高并发场景下。
  • 订单号较长:为了降低重复风险,随机数位数可能需要较多,导致订单号长度较长。

2.2.4 使用场景

  • 适用于订单量相对较小的场景,或者系统没有严格的分布式需求时可以使用。

2.3 订单类型 + 日期 + 序号

2.3.1 实现方式

  • 将订单的类型日期(通常是年月日)、序号等元素组合生成订单号。
    • 订单类型:如"01"表示普通订单,"02"表示VIP订单等。
    • 序号:可以是每日从1开始自增的序号,也可以是数据库或 Redis 自增的序列。

2.3.2 优点

  • 可读性好:通过订单号可以直接识别订单类型和生成日期,方便系统管理和客户服务。
  • 灵活性高:序号部分可以根据不同的订单类型或日期进行自增,不同类型的订单可以独立生成序列。

2.3.3 缺点

  • 重复风险:如果序号设计不合理,可能在并发场景下出现重复订单号的风险(例如相同订单类型和日期)。
  • 依赖外部存储:序号部分通常依赖于数据库或 Redis 来保证唯一性,存在性能瓶颈。

2.3.4 使用场景

  • 适用于订单量较大、订单类型较多的场景,方便通过订单号直接获取订单的基本信息。

2.4 分布式唯一ID生成器(如 Snowflake 算法)

2.4.1 实现方式

  • 使用分布式唯一ID生成算法(如 Snowflake 算法)生成全局唯一的订单号。Snowflake 是 Twitter 开发的一种算法,它基于时间戳机器ID序列号来生成唯一ID。

2.4.2 优点

  • 全局唯一:生成的订单号保证在分布式系统中的唯一性,无需依赖数据库或其他外部存储。
  • 高效性:算法可以在短时间内生成大量的唯一ID,性能高效。
  • 趋势递增:生成的ID具有时间上的趋势递增性,易于排序。

2.4.3 缺点

  • 实现复杂:需要部署和维护分布式ID生成服务,或者集成第三方工具,增加了系统的复杂性。
  • 不可读性:生成的ID通常是较长的数字,无法通过订单号直接获取有用的订单信息。

2.4.4 使用场景

  • 适用于高并发、大规模分布式系统,需要保证订单号全局唯一性且性能要求较高的场景。

3. 总结

  • 小型系统、单点系统:使用自增序列(数据库或 Redis INCR)即可,简单易实现,但需要注意系统扩展性和性能瓶颈。
  • 需要包含时间信息的订单号:可以使用时间戳 + 随机数,通过随机数降低重复风险,适合小型系统。
  • 订单类型明确的系统:可以使用订单类型 + 日期 + 序号,不仅保证唯一性,还能通过订单号获取有用信息,适合有不同订单类型的系统。
  • 高并发分布式系统:推荐使用分布式唯一ID生成器(如 Snowflake 算法),高效、唯一、支持分布式,是大型系统和高并发系统的首选。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

cyt涛

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值