【问题标题】:Generating serial or unique ordernumber生成序列号或唯一订单号
【发布时间】:2010-06-21 05:46:53
【问题描述】:

如何在不检查db的情况下在php中生成唯一的序列号或订单号?

【问题讨论】:

    标签: php auto-increment serial-number


    【解决方案1】:

    参见uuid peclcom_create_guid() 中的uniqiduuid_create

    【讨论】:

      【解决方案2】:

      如果你想保证唯一性,那么你必须检查一些东西。您可以使用平面文件并仅存储最近使用的数字(然后您可以递增),但不使用数据库会很愚蠢。您需要存储大量与号码相关联的其他信息(联系方式、订单内容等),数据库非常适合。

      【讨论】:

      • 如果我从这样的日期字符串生成日期(YmbHis),如果网站被大量使用,它会是唯一的吗
      • ^特别是如果您的服务器遵守 DST。我认为最好只检查数据库(或者按照 Thomas 的建议让它为您生成订单号)。它对数据库的负担并不重,即使是这样,您每分钟生成的订单号也可能不会超过几十个。
      【解决方案3】:

      在 mysql 中使用自动增量列存在几个问题(尤其是它不能扩展到等效节点的事实)。

      虽然您几乎可以在任何地方(内存缓存、文件、数据库)维护序列生成器,但 PHP 并没有实现复杂的文件锁定语义 - 除了影响性能之外,您还可以快速进入解除锁定情况。它不能扩展到大容量。

      如果您有可用的 PL/SQL,那么我建议您在那里实现一个序列生成器 - 或者您可以考虑在 PHP 和 sqlite 中实现一个生成器。

      我强烈建议您实现生成器来创建格式数字:

      $use_number = ++$sequence_number 。 str_pad($node_id, '0', $max_nodes, STR_PAD_LEFT);

      其中 node_id 是唯一引用存储当前序列号的存储基板的数字。并且 $max_nodes 比 $node_id 中的最大位数略多(例如,3 最多允许 999 个节点)。

      或者将其视为两个部分之间带有标点符号的字符串(和/或将这两个部分存储在不同的数据库列中)。

      C.

      【讨论】:

        【解决方案4】:

        如果您使用的是 MySQL 数据库,则可以使用auto_increment 列生成序列号,而无需预先检查数据库。插入新行将导致为该列分配一个新的唯一 ID,而无需在 PHP 中读取/写入该列。

        或者,如果您想要一个全局唯一 ID,甚至不需要数据库,那么您可以使用 PHP 的 uniqid() 函数。请注意,这将返回一个字符串。如果您使用多台物理机器或在服务器之间移动,您应该添加在每台机器上都不同的前缀(第一个参数)。在同一台机器上使用时,此函数不应返回相同的字符串值两次。

        【讨论】:

        • 可以mysql_return最后一个唯一id而不重新查询数据库吗?
        • @Smith: php.net/manual/en/function.mysql-insert-id.php(但不确定它是否请求。)
        • 我怀疑 mysql_insert_id 是否创建了一个新的数据库查询,给出了描述(例如,它的保留时间少于 MySQL 的 LAST_INSERT_ID())。但这是个好问题。