本文介绍了在 InnoDB 中使用 MAX 模拟自动增量的最快和最安全的方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我们有一个具有以下架构的表:

Assume that we have a table with the following schema:

CREATE TABLE Persons (
sid int NOT NULL AUTO_INCREMENT,
groupName varchar(255) NOT NULL,
userIdInGroup int,
PRIMARY KEY (sid));

我们希望根据组的最后一个 userId 为同一组中的每个新用户分配一个自动递增的 userId,即我们希望在每个组内模拟一个自动递增的 userId.

We want to assign each new user in the same group an auto-increment userId based on the last userId of the group, i.e. we want to emulate an auto-increment userId within each group.

由于我们考虑 MAX(userIdInGroup) 插入新的 userId,因此我们需要将 select 和 insert 包装到事务中.像这样:

Since we are inserting the new userId considering the MAX(userIdInGroup) we need to wrap select and insert in a transaction. Something like this:

START TRANSACTION
SET @a = (SELECT MAX(userIdInGroup) FROM Persons WHERE groupName= 'Foo') +1;
INSERT THE NEW ROW USING userIdInGroup = @a
COMMIT 
  1. 只是在事务中选择 MAX 是安全的还是我们需要通过 SELECT FOR UPDATE 锁定某些内容?
  2. 有没有办法绕过事务并保持一致?

推荐答案

我不是 MySql 人,但我对其他数据库有足够的经验,我知道这是一个非常糟糕的主意.这个 UserIdInGroup 可以使用 row_number 轻松计算:

I'm not a MySql person, but I do have enough experience with other databases to know that this is a really bad idea. This UserIdInGroup can easily be calculated using row_number:

SELECT sid, 
       groupName, 
       ROW_NUMBER() OVER(PARTITION BY groupName ORDER BY sid) AS userIdInGroup
FROM Persons

除了滚动您自己的自动增量通常最终会给出错误的数字(尤其是在多线程环境中)之外,您可以轻松计算的内容(在代码和性能方面)不应存储无论如何.

And besides the fact that rolling your own auto-increment usually ends up giving wrong numbers (especially in a multi-threaded environment), what you can calculate easily (both in the code and in the performance aspect) should not be stored anyway.

这篇关于在 InnoDB 中使用 MAX 模拟自动增量的最快和最安全的方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-30 03:20