Эмулировать автоинкремент в MySQL / InnoDB - PullRequest
2 голосов
/ 20 июля 2010

Предположим, я собираюсь эмулировать автоинкремент в MySQL / InnoDB

Условия

  1. Использование MySQL / InnoDB
  2. Поле идентификатора не имеет уникальногоиндекс, также это не PK

Возможно ли эмулировать только с помощью программной логики, без блокировки на уровне таблицы.Спасибо.

Ответы [ 4 ]

3 голосов
/ 24 июля 2010

Используйте таблицу последовательности и триггер - что-то вроде этого:

drop table if exists users_seq;

create table users_seq
(
next_seq_id int unsigned not null default 0
)engine = innodb;

drop table if exists users;

create table users
(
user_id int unsigned not null primary key,
username varchar(32) not null
)engine = innodb;

insert into users_seq values (0);

delimiter #

create trigger users_before_ins_trig before insert on users
for each row
begin

declare id int unsigned default 0;

  select next_seq_id + 1 into id from users_seq;

  set new.user_id = id;

  update users_seq set next_seq_id = id;

end#

delimiter ;

insert into users (username) values ('f00'),('bar'),('bish'),('bash'),('bosh');

select * from users;
select * from users_seq;

insert into users (username) values ('newbie');

select * from users;
select * from users_seq;
2 голосов
/ 20 июля 2010
CREATE TABLE sequence (id INTEGER); -- possibbly add a name;
INSERT INTO sequence VALUES (1); -- starting value

SET AUTOCOMMIT=0;
START TRANSACTION;
UPDATE sequence SET id = LAST_INSERT_ID(id+1);
INSERT INTO actualtable (non_autoincrementing_key) VALUES (LAST_INSERT_ID());
COMMIT;

SELECT LAST_INSERT_ID(); Это даже безопасное для сеанса значение, чтобы проверить, какой идентификатор вы получили. Убедитесь, что ваша таблица поддерживает транзакции или что дыры в последовательности не являются проблемой.

2 голосов
/ 20 июля 2010

Создайте еще одну таблицу с одной строкой и столбцом, в которой будет храниться следующее значение идентификатора.Затем создайте триггер вставки в исходной таблице, который увеличивает значение во второй таблице, захватывает его и использует его для столбца ID в первой таблице.Вам нужно быть осторожным с тем, как вы делаете выбор и обновление, чтобы убедиться, что они атомарны.

По сути, вы эмулируете Oracle sequence в MySQL.Это может привести к блокировке одной строки в таблице последовательности, что может сделать его неприемлемым для того, что вы делаете.создайте вторую таблицу «последовательность», в которой только один столбец PK с автоматическим приращением и нет других данных.Сделайте так, чтобы ваш триггер вставки вставил строку в эту таблицу и использовал сгенерированный идентификатор, чтобы заполнить идентификатор в исходной таблице.Затем либо запустите триггер, либо другой процесс, периодически удаляйте все строки из таблицы последовательности, чтобы очистить его.

0 голосов
/ 24 июля 2010
Таблица последовательности

должна иметь идентификатор в качестве автоинкремента PK

...