假设我们有一个具有以下架构的表:
CREATE TABLE Persons (
sid int NOT NULL AUTO_INCREMENT,
groupName varchar(255) NOT NULL,
userIdInGroup int,
PRIMARY KEY (sid));
我们想要基于组的最后一个userId为同一组中的每个新用户分配一个自动递增的userId,即我们要在每个组中模拟一个自动递增的userId。
由于我们要考虑MAX(userIdInGroup)插入新的userId,因此需要包装选择并插入事务中。像这样:
START TRANSACTION
SET @a = (SELECT MAX(userIdInGroup) FROM Persons WHERE groupName= 'Foo') +1;
INSERT THE NEW ROW USING userIdInGroup = @a
COMMIT
仅在事务中选择MAX是安全的还是我们需要通过SELECT FOR UPDATE锁定某些内容?
无论如何有绕过交易并且仍然保持一致吗?
最佳答案
我不是MySql的人,但是我在其他数据库上确实有足够的经验,知道这是一个非常糟糕的主意。该UserIdInGroup
可以使用row_number
轻松计算:
SELECT sid,
groupName,
ROW_NUMBER() OVER(PARTITION BY groupName ORDER BY sid) AS userIdInGroup
FROM Persons
除了滚动自己的自动增量通常会导致输入错误的数字(特别是在多线程环境中)之外,您无论如何容易地计算出的内容(无论是在代码方面还是在性能方面)都不应存储。