背景:我正在开发一个系统,其中开发人员似乎正在使用一个函数来执行 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 Baker 的观点,有一些性能方面的考虑,但由于 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/