最后插入id方法可靠吗

Posted

技术标签:

【中文标题】最后插入id方法可靠吗【英文标题】:Is last insert id method reliable 【发布时间】:2018-10-10 08:48:48 【问题描述】:

以下场景。

我们有 2 个脚本,都插入到表中,然后使用 lastInsertId() 从自动增量列中获取值。

如果这两个脚本并行执行,我们确定它们不会弄乱结果吗?


实时:

时间 1:脚本 1 -> 插入。 (创建的 id = 1)

时间 1:脚本 2 -> 插入。 (创建 id = 2)

(数据库可能使用锁/信号量来处理这个问题)

Q1. 时间 2:脚本 2 -> lastInsertId() 返回 1 还是 2?它是确定性的吗?

Q2. 那么顺序插入呢?

script.php

$statement1->insert('john'); // id = 1
$statement2->insert('mary'); // id = 2

echo $statement1->lastInsertId();
// is it 1 or 2? Is this also deterministic? 

【问题讨论】:

'If a sequence name was not specified for the name parameter, PDO::lastInsertId() returns a string representing the row ID of the last row that was inserted into the database.' 所以如果我指定名称,我保证正确的结果?另外,你能告诉我,如果我使用交易,我上面的问题不再重要了吗? Q2:是 1 还是 2 它将是 2,因为连接只记住 LAST 插入的密钥。因此,如果您需要记住它,则必须在每次插入后捕获两次密钥 Q1:连接会记住最后的插入id。因此,由于每个脚本都有自己的连接,因此每个脚本都会记住使用其连接发生的 INSERT @RiggsFolly 如果我使用持久连接,Q1 的答案是否仍然正确? 【参考方案1】:

是的,它是可靠的。

如果您认为一个表每秒将有数百或数千次插入,请考虑不使用索引或使用最少数量的索引。在 mysql 的情况下,偏爱 MyISAM 表。

在你的情况下,

Q1. 时间 2:脚本 2 -> lastInsertId() 返回 1 还是 2?它是确定性的吗?

返回第二个查询的 id。

Q2. 那么顺序插入呢?

您必须确保在插入查询之后询问 lastInsertId。

希望对你有帮助。

【讨论】:

【参考方案2】:

是的,它是可靠的。

lastInsertId() 顾名思义,会保存最后插入的行的id(主键)。

所以关于 Q1: 答案是 2,因为那是最后插入的行。

当涉及到顺序插入时,并且您想“做某事”围绕lastInsertId()的使用,那么您必须声明lastInsertId() 完全正确 em> 在(这很重要)执行的查询行之后。这样你就一定会持有你想要使用的id

->an insert query is executed
->lastInsertId() is stored into a variable
->variable is used for something
->another insert query is executed
->another lastInsertId is stored into a variable
->variable is used for something.
etc...

同样的逻辑也适用于循环。

您不一定必须将lastInsertId() 存储到变量中,但如果您使用PHP 并需要将其用于多种用途,这很有意义。如果没有,那么您可以直接在相关查询中使用它。但请记住,它必须在您希望使用的 id 的指定插入之后正好

失败逻辑示例:

<?php
//I want to get id 1
$statement1->insert('john'); // id = 1
$statement2->insert('mary'); // id = 2
$lastId=$statement1->lastInsertId();
?>

这将是一个失败的逻辑,因为我的意图是检索 id 1,但由于我正在等待在语句 2 之后检索我的 lastInsertId() 而不是语句 1,所以我的 lastInsertId() 将等于 2 而不是1.

工作逻辑:

<?php
//I want to get id 1
$statement1->insert('john'); // id = 1
$lastId=$statement1->lastInsertId();
//do something with $lastId? (value will be 1)
//get contact info from a theoretical contact info table
$sql="SELECT * FROM tbl_contacts WHERE userId='$lastId'";
$statement2->insert('mary'); // id = 2
$lastId=$statement2->lastInsertId();
//do something with $lastId? (value will be 2)
?>

这个逻辑会起作用,因为我正在检索我想要的 id 值,并在它们被另一个 id 覆盖之前使用它们。

您当然可以使包含 lastInsertId() 值的变量唯一,这样它们就不会被覆盖,然后您可以随时使用它们。

【讨论】:

以上是关于最后插入id方法可靠吗的主要内容,如果未能解决你的问题,请参考以下文章

主板 ID - WMI C++ - 可靠吗?

如何获取Android设备用户移动的速度? Location.getSpeed 可靠吗?

在android中使用JDBC安全可靠吗?

字节一面:HTTPS 一定安全可靠吗?

疲劳可靠性设计的基础是什么,知道吗?

$_SERVER['REQUEST_SCHEME'] 可靠吗?