php - 在 MYSQL 中使用 SELECT MAX(id) 而不是在 PHP 中使用 mysql_insert_id() 有多糟糕?

标签 php mysql concurrency mysql-insert-id

背景:我正在开发一个系统,其中开发人员似乎正在使用一个函数来执行 MYSQL 查询,例如 "SELECT MAX(id) AS id FROM TABLE" 每当他们需要获取最后插入的行的 ID(具有 auto_increment 列的表)。

我知道这是一种可怕的做法(因为并发请求会弄乱记录),我正在尝试将其传达给非技术/管理团队,他们的回应是......

"Oh okay, we'll only face this problem when we have 
(a) a lot of users, or 
(b) it'll only happen when two people try doing something
    at _exactly_ the same time"

我不反对任何一点,并且认为我们会比计划更快地遇到这个问题。但是,我正在尝试计算(或想出一种机制)来计算在我们开始看到困惑的链接之前应该使用该系统的用户数。

对此有什么数学见解吗?同样,我知道这是一种可怕的做法,我只想了解这种情况下的变量...


更新:感谢大家的评论 - 我们正朝着正确的方向前进并修复代码!

最佳答案

重点不在于是否可能出现潜在的不良情况。关键是它们是否可能。只要问题发生的可能性很大,如果已知,就应该避免。

我们并不是在谈论将单行函数调用更改为 5000 行的怪物来处理远程可能的边缘情况。我们正在谈论实际缩短调用,使其更易读、更正确。

我有点同意@Mark Ba​​ker 的观点,有一些性能方面的考虑,但由于 id 是主键,MAX 查询会非常快。当然,LAST_INSERT_ID() 会更快(因为它只是从 session 变量中读取),但只是微不足道的数量。

而且您不需要很多用户就可以做到这一点。您所需要的只是大量并发请求(甚至没有那么多)。如果插入的开始和选择的开始之间的时间是 50 毫秒(假设事务安全的数据库引擎),那么您每秒只需要 20 个请求就可以开始始终如一地遇到问题.关键是错误窗口是非常重要的。如果您说每秒 20 个请求(实际上并不算多),并假设普通人每分钟访问一个页面,那么您只是在谈论 1200 个用户。这是为了定期发生。只有 2 个用户可能会发生一次。

MySQL documentation on the subject 开始:

You can generate sequences without calling LAST_INSERT_ID(), but the utility of 
using the function this way is that the ID value is maintained in the server as 
the last automatically generated value. It is multi-user safe because multiple 
clients can issue the UPDATE statement and get their own sequence value with the
SELECT statement (or mysql_insert_id()), without affecting or being affected by 
other clients that generate their own sequence values.

关于php - 在 MYSQL 中使用 SELECT MAX(id) 而不是在 PHP 中使用 mysql_insert_id() 有多糟糕?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3511826/

相关文章:

php - Mysql 连接两个表的 where 子句

mysql - 获取在同一订单中购买了三件指定商品的所有客户

c++ - 为什么在使用 8 个生产者 1 个消费者进行测试时,golang channel 比 intel tbb concurrent_queue 快得多

java - 尽管没有代码明确泄漏未初始化的对象泄漏到另一个线程?

php - 在 php 中上传和显示(选择)视频

php - 期望 Json 输出格式为 Like [ { },{ } ]

php - 为什么我不能包含博客?

MySQL - 过滤两列中具有完全相同十进制值的行

MYSQL关于ROOT用户的安全问题

java - ReentrantLock 未给出预期结果