Самый быстрый и безопасный способ эмуляции автоинкремента с использованием MAX в InnoDB - PullRequest
0 голосов
/ 24 января 2019

Предположим, что у нас есть таблица со следующей схемой:

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

Мы хотим назначить каждому новому пользователю в той же группе автоматическое увеличение userId на основе последнего userId группы, т.е.хочу эмулировать автоматически увеличивающийся userId в каждой группе.

Поскольку мы вставляем новый userId с учетом MAX (userIdInGroup), нам нужно обернуть select и вставить в транзакцию.Примерно так:

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. Есть ли способ обойти транзакцию и до сих порбыть последовательным?

1 Ответ

0 голосов
/ 24 января 2019

Я не MySql, но у меня достаточно опыта работы с другими базами данных, чтобы понять, что это действительно плохая идея.Это UserIdInGroup может быть легко вычислено с использованием row_number:

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

И помимо того факта, что прокрутка собственного автоинкремента обычно приводит к неправильным числам (особенно в многопоточной среде), чтоВы можете легко рассчитать (как в коде, так и в аспекте производительности) не должны быть сохранены в любом случае.

...