Fastest and Safest Way to Emulate Auto-Increment using MAX in InnoDB

白昼怎懂夜的黑 提交于 2020-01-25 10:17:07

问题


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));

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.

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. Is just selecting MAX in a transaction safe or do we need to lock something by SELECT FOR UPDATE?
  2. Is there anyway to bypass transaction and still be consistent?

回答1:


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.



来源:https://stackoverflow.com/questions/54341289/fastest-and-safest-way-to-emulate-auto-increment-using-max-in-innodb

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!