【问题标题】:Can I assume the highest auto increment value is always the newest entry?我可以假设最高的自动增量值总是最新的条目吗?
【发布时间】:2018-05-14 19:31:13
【问题描述】:

我有以下代码从表中获取最新条目。

$con = mysqli_connect($host,$username,$password,$database);
$result = $con->query("SELECT MAX(ID) FROM Samples");
$newest = $result->fetch_assoc();

字段ID 是主键,具有自动增量。我没有代码可以更改ID 的值。

当我测试代码时,它总是成功地产生最新的条目,但我不知道这是否是我可以依赖的行为。这会一直有效吗?如果没有,是否有更可靠的方法来获取最新条目?

【问题讨论】:

  • 答案是肯定的。
  • 这几乎是真的,但不是 总是 因为某些极端情况......我特别考虑 MyISAM 对组的 AUTO_INCREMENT 特殊处理,当 autoinc 列不是第一个时索引中的列。此外,innodb_autoinc_lock_mode 可以影响多个并发会话的行为,并且没有什么可以阻止语句为 AUTO_INCREMENT 列提供值(如果没有提供值,则会自动分配值,或者提供 NULL 值或 0 值。(不要依赖MAX(id) 来获取前一个 INSERT 的 auto_increment 值。)

标签: mysql sql auto-increment


【解决方案1】:

SELECT MAX(ID) FROM ... 会一直有效吗?

不,它不会。如果您有多个程序副本连接到数据库,并且一个程序执行您的建议,然后另一个程序执行插入,则第一个程序的MAX(ID) 值将变得陈旧。这是一个竞赛条件。这些很难检测和调试,因为它们在系统负载过重时才会出现。

如果您只关心MAX(ID) 的快照,您会没事的。但是您不能将此MAX(ID) 值用作下一次插入的值,除非您永远 将有多个程序实例插入数据。依赖那种从不。

如果没有,有没有更可靠的方法来获取最新条目?

在执行 INSERT 操作后,您可以立即执行 SELECT LAST_INSERT_ID() 来检索刚刚使用的自动递增 ID。当 INSERT 操作完成时,各种 API(如 mysqliPDOJDBC)会将此 ID 返回给调用程序。

LAST_INSERT_ID() and the related API functions 在一个连接一个连接的基础上工作。因此,如果多个连接都在插入行,每个连接都会有自己的 id 值。

【讨论】:

  • 此外,最后两个条目也有可能来自两个不同的交易。一个人可能已经“保留”了较早的 id “插槽”,但后来完成了......这就需要定义“最新”的含义。
  • 从问题中看不清楚他是想获取刚刚插入的行的ID,还是一般只是想获取最近的ID。
  • @Barmar 我应该说清楚的。我想要我刚刚插入的行的 ID。
  • @SarcasticSully 那么LAST_INSERT_ID() 确实是这样做的方法。它也可以通过$con->insert_id 获得。
  • @SarcasticSully 是的。来自documentation:生成的 ID 在服务器中基于每个连接进行维护。这意味着函数返回给给定客户端的值是为影响该客户端的 AUTO_INCREMENT 列的最新语句生成的第一个 AUTO_INCREMENT 值。
【解决方案2】:

MySQL 具有自动递增功能,您可以使用以下方法将列设置为自动递增

ALTER TABLE document MODIFY COLUMN ID INT auto_increment

然后您可以将条目添加到表中,而不必担心 Id,使用 max 可能会出现问题,尤其是当可以在您正在构建的系统之外修改数据时,例如通过直接输入到表中。要插入记录,请将 Id 保留为空。

我希望这会有所帮助,干杯!

【讨论】:

    猜你喜欢
    • 2018-01-19
    • 2012-03-26
    • 2019-09-20
    • 2014-02-21
    • 2019-04-06
    • 1970-01-01
    • 2012-11-30
    • 2021-01-13
    • 2012-10-01
    相关资源
    最近更新 更多