【问题标题】:Generating sequential ID using MySQL使用 MySQL 生成顺序 ID
【发布时间】:2020-08-10 10:02:42
【问题描述】:

我需要为收到的每个订单生成条形码参考。第一个条码为 200000,随后的每个订单增加 1。我必须绝对确定我不会将相同的条形码分配给多个订单。该项目收到大量订单,而且很多订单接连不断。

为了克服这个问题,我创建了一个名为 barcodes 的 MySQL 数据库表,并带有一个自动递增的主键。第一行的ID是200000。

每次我需要生成条形码时,我都会插入barcodes 表,然后使用PHP 的mysqli_insert_id() 来插入ID。然后我更新orders 表,以便将条形码设置为此值。

这很好用,可以防止我将相同的条形码分配给多个订单。

有没有更好的方法?理想情况下,我会有一个表来存储下一个可用 ID,然后运行两个查询:

select next_barcode from barcodes where id=1

然后

update barcodes set next_barcode=next_barcode+1 where id=1

我担心的是,我的代码可能会在运行的同时(即在 UPDATE 之前)调用执行 SELECT 的函数,并且给两个订单提供相同的条形码。

也许有一些可靠的表锁定方法?或者也许我目前的方法是最好的方法?

【问题讨论】:

    标签: mysql database sql-update sql-insert auto-increment


    【解决方案1】:

    你做的很好。您将保证不会两次获得相同的 id。 如果您为此发明自己的系统,您将需要锁定许多表,破坏并发性或通过事务完成所有操作。绝对有可能完成您对事务所做的事情,但最好的方法可能主要是复制 AUTO_INCREMENT 已经做的事情。只是更难。

    请记住,在某些情况下,MySQL 可能会跳过 AUTO_INCREMENT 中的 id,但您可以保证永远不会两次获得相同的数字。

    【讨论】:

    • 谢谢你,埃弗特。我偶尔跳过一个 ID 没有问题,我只需要避免反向使用相同的 ID 两次。
    【解决方案2】:

    就问题而言,您当前使用的auto_increment 是适合您的用例的最佳方式。 通过设计保证了唯一性,并且数据库在后台为您完成了繁重的工作。

    唯一可能的缺点是您可能会在ids 中遇到间隙-例如,当insert 由于某种原因失败时,序列id 可能会丢失,并且以下插入将增加@987654325再次@,导致序列中的空白。

    如果这对您来说是个问题,那么一种选择是在插入时使用insert ... select 语法在单个查询中获取最新的 id 和新的 id,例如:

    insert into barcodes (id, ...)
    select coalesce(max(id), 0) + 1, ...
    from barcodes
    

    这可以防止两行获得相同的id。但同样,我不建议这样做;使用auto_increment 更高效、更简单。

    【讨论】:

    • 谢谢你,GMB。很高兴知道我使用的“简单”方法很好。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-03-28
    • 2011-02-26
    • 2010-11-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多