2010-07-20 3 views
2

Предположим, я буду подражать автоинкрементируемого в MySQL/InnoDBЭмуляция автоинкрементным в MySQL/InnoDB

Условия

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

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

ответ

2

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

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

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

По сути, вы эмулируете Oracle sequence в MySQL. Это приведет к блокировке одной строки в таблице последовательностей, так что это может сделать ее неприемлемой для того, что вы делаете.

ETA:

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

2
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(); даже сеанс безопасного значения для проверки, которые вы получили ID. Убедитесь, что ваши таблицы поддерживают транзакции, или что дыры в последовательности не являются проблемой.

0

таблица последовательности должны иметь идентификатор как автоинкремент PK

Смежные вопросы