Автоинкремент MySQL InnoDB, такой как MyISAM

MyISAM позволяет очень удобно создавать сериалы. Например. В таблице первичный ключ id+seq(-uence)

id seq
1  1  insert into table(seq) values(1),(2),(3),(1),(2),(1),(1),(2);
1  2
1  3
2  1
2  2
3  1
4  1
4  2

Таким образом, логика заключается в том, что идентификатор остается неизменным до тех пор, пока не появится дублирующийся ключ, в этом случае (MyISAM) будет увеличивать идентификатор.

Но когда я пытаюсь использовать его в InnoDB - не работает. Есть ли обходной путь (потому что мне нужны транзакции)?

Спасибо.

Может быть, лучший пример из комментариев к Руководству по MySQL. Автор: [имя не разглашается] 23 октября 2003 г., 20:41.

create table location
(
    id bigint not null auto_increment, -- "serial" per 4.1
    longitude int,
    latitude int,
    place int,
    primary key(id, longitude, latitude, place)
);

insert into location (longitude, latitude, place)
values (0,0,0), (1,1,1), (2,2,2);

select * from foo;

+----+-----------+----------+-------+
| id | longitude | latitude | place |
+----+-----------+----------+-------+
|  1 |         0 |        0 |     0 |
|  2 |         1 |        1 |     1 |
|  3 |         2 |        2 |     2 |
+----+-----------+----------+-------+


drop table location;

create table location
(
    id bigint not null auto_increment, -- "serial" per 4.1
    longitude int,
    latitude int,
    place int,
    primary key(longitude, latitude, place, id)
);

insert into location (longitude, latitude, place)
values (0,0,0), (1,1,1), (2,2,2), (0,0,0);

select * from location order by id;

+----+-----------+----------+-------+
| id | longitude | latitude | place |
+----+-----------+----------+-------+
|  1 |         0 |        0 |     0 |
|  1 |         1 |        1 |     1 |
|  1 |         2 |        2 |     2 |
|  2 |         0 |        0 |     0 |
+----+-----------+----------+-------+

person Lorenzo Manucci    schedule 17.06.2011    source источник
comment
Я предполагаю, что вы говорите о функции MyISAM, когда первичный ключ является составным. Если это так, то нет, такая функция недоступна для InnoDB. Обходной путь — угробить авто_инкремент, написать свою процедуру вычисления ключа — в принципе, огромные мороки.   -  person Michael J.V.    schedule 17.06.2011


Ответы (2)


Но когда я пытаюсь использовать его в InnoDB - не работает. Есть ли обходной путь (потому что мне нужны транзакции)?

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

См. этот идентичный вопрос для PostgreSQL . Вы захотите написать версию MySQL того же самого.

person Denis de Bernardy    schedule 17.06.2011
comment
Спасибо, но мне нужно вставить в транзакцию около 20 таблиц (смежное сопоставление xml), поэтому мне нужно сделать управление транзакциями как можно более простым. - person Lorenzo Manucci; 17.06.2011
comment
Что ж, более простым способом сделать это будет блокировка таблицы по мере необходимости. Но это будет медленнее. - person Denis de Bernardy; 17.06.2011

Это будет работать:

create table location
(
    id bigint not null auto_increment,
    longitude int,
    latitude int,
    place int,
    primary key(longitude, latitude, place, id)
) ENGINE =myisam;

Но этого не будет:

create table location
(
    id bigint not null auto_increment,
    longitude int,
    latitude int,
    place int,
    primary key(longitude, latitude, place, id)
) ENGINE =innodb;

так как:

Недостатки MyISAM

Нет проверки целостности данных (например, ограничений отношений), что затем ложится ответственностью и накладными расходами на администраторов баз данных и разработчиков приложений.

и

Недостатки InnoDB

Поскольку InnoDB должен заботиться о различных отношениях между таблицами, администратору базы данных и создателям схем приходится тратить больше времени на разработку более сложных моделей данных, чем у MyISAM.

person Utsav    schedule 17.07.2012
comment
Я обнаружил, что это будет работать для меня в innoDB, если я сделаю поле автоинкремента первой частью первичного ключа. - person Gerry; 18.10.2013