一种生成订单号的好算法

时间:2009-12-01 03:46:49

标签: algorithm math

尽管我喜欢使用GUID作为我系统中的唯一标识符,但对于客户可能不得不向客户服务代表重复的订单号这样的字段来说,它不是非常用户友好。

用于生成订单号的好算法是:

  • 唯一
  • 不顺序(纯粹用于光学)
  • 仅限数字值(因此可以通过电话或键入内容轻松读取CSR)
  • < 10位数
  • 可以在中间层生成而无需往返数据库。

更新(12/05/2009) 在仔细查看发布的每个答案后,我们决定将中间层中的9位数字随机化,以保存在数据库中。在发生碰撞的情况下,我们将重新生成一个新数字。

10 个答案:

答案 0 :(得分:8)

如果中间层无法检查数据库中已存在的“订单号”,那么它能做的最好就相当于生成一个随机数。但是,如果生成的约束小于10亿的随机数,则应该开始担心sqrt(1 billion)附近的意外碰撞,即在以这种方式生成数万个条目之后,碰撞的风险是材料。如果订单号是连续的但是以伪装的方式,即一些模数为10亿的大质数的下一个倍数 - 会满足您的要求怎么办?

答案 1 :(得分:5)

< Moan> OK听起来像是过早优化的经典案例。你想象一个性能问题(哦,我的上帝,我必须访问 - 恐怖 - 数据库,以获得一个订单号!我可能会很慢)并最终得到一个混乱的伪造随机生成器和大量重复处理代码。< ; /呻吟>

一个简单的实际答案是按客户运行序列。实际订单号是客户编号和订单编号的组合。您可以轻松检索重新获取有关客户的其他内容时使用的最后一个序列。

答案 2 :(得分:2)

一个简单的选择是使用日期和时间,例如。 0912012359,如果在同一分钟收到两个订单,只需将第二个订单递增一分钟(如果时间结束则无关紧要,它只是一个订单号。)

如果您不希望日期可见,请将其计算为自固定时间点以来的分钟数,例如。当你开始接受订单或其他一些仲裁日期时。再次,重复检查/增量。

你的竞争对手不会从中收集任何东西,而且很容易实现。

答案 3 :(得分:1)

也许您可以尝试使用马尔可夫链生成一些独特的文本 - 请参阅here以获取Python中的示例实现。也许使用序号(而不是随机数)来生成链,这样(希望)每个订单号都是唯一的。

只是一个警告 - 请参阅here,了解如果您对设置不小心可能会发生什么。

答案 4 :(得分:1)

一种解决方案是采用订单某些字段的哈希值。这并不能保证它与所有其他订单的订单号不同,但碰撞的可能性非常低。我想如果没有“对数据库进行往返”,确保订单号是唯一的是具有挑战性的。

如果您不熟悉哈希函数,维基百科页面非常好。

答案 5 :(得分:1)

你可以对一个guid进行base64编码。除了“仅限数值”要求外,这将满足您的所有条件。

但是,真的,正确要做的就是让数据库生成订单号。这可能意味着创建一个订单模板记录,该记录实际上没有订单号,直到用户保存它,或者它可能正在添加创建的能力(但也许未提交的订单。

答案 6 :(得分:1)

使用原始多项式作为有限域生成器。

答案 7 :(得分:1)

您的10位数要求是一个巨大的限制。考虑两阶段方法。

  1. 使用GUID
  2. 使用GUID的10位(或5位或4位)哈希对GUID进行前缀。
  3. 哈希值会有多次点击。但不是那么多。客户服务人员将很容易根据客户提供的其他信息确定哪个订单有问题。

答案 8 :(得分:0)

大多数要点的直截了当的答案:

将前六位数字设为顺序增加字段,并在末尾附加三位哈希值。或者七个和两个,或八个和一个,取决于你想要支持的订单数量。

但是,您仍然需要在后端调用一个函数来保留新的订单号;否则,不可能保证不发生碰撞,因为数字很少。

答案 9 :(得分:0)

我们做TTT-CCCCCC-1A-N1。

  • T =电路类型(D1E = DS1 EEL,D1U = DS1 UNE等)
  • C = 6位客户ID
  • 1 =客户的第一个位置
  • A =此位置的第一个电路(A = 1,B = 2等)
  • N =订单类型(N =新,X =断开连接等)
  • 1 =此电路的第一个此类订单