Pdo, postgresql, lastinsertid

WMix

герр M:)ller
Партнер клуба
По той причине, что функция nextval возвращает новое значение говорит о том что она хранит состояние (она не pure). Но это значение не часть данных это просто вспомогательный механизм. Все перечисленные тобою плюсы последовательности решаются и с помощью вспомогательной таблички с единственным autoincrement полем. Несколько табличек - несколько последовательностей. И это тоже атомарно, с такимже спинлоком на низком уровне.
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
вероятно, ты хотел сказать, что nextval неидемпотентная

использовать приватный ключ таблицы для эмуляции восходящей последовательности можно; задать диапазон, реализовать нисходящую и зациклить не получится

предполагаю, что overhead на таблицу больше, чем на последовательность, но не проверял

еще последовательность можно реализовать через UDF
 

Вурдалак

Продвинутый новичок
Если чо, в мануале по MySQL есть простой пример эмуляции sequences через таблицу: https://dev.mysql.com/doc/refman/5.7/en/innodb-locking-reads.html
Код:
UPDATE child_codes SET counter_field = LAST_INSERT_ID(counter_field + 1);
SELECT LAST_INSERT_ID();
Мы делаем на каждый псевдо-sequence свою таблицу, просто чтобы минимизировать шанс факапа (если сделать неловкий UPDATE без WHERE, то все пойдет по пзде; а таблица сверхмаленькая, забыть реально).

Также нужно следить, чтобы получение значения из sequence через способ выше не попало в транзакцию. Можно напилить обертку, которая в явном виде будет бросать исключение , если сейчас мы в транзакции.
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
autoincrement с LAST_INSERT_ID() - это специальная олимпиада
если не учитывать целой кучи неожиданных правил, легко отстрелить себе ногу:
Код:
CREATE TABLE `T1` (
   `id1` INT NOT NULL AUTO_INCREMENT PRIMARY KEY
);
CREATE TABLE `T2` (
   `id2` INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
   `t1id` INT NOT NULL,
   FOREIGN KEY (t1id) REFERENCES T1(id)
);
первая вставка с id=null:
Код:
INSERT INTO `T1` (`id`) VALUES (NULL);
SET @lastID := LAST_INSERT_ID();
INSERT INTO `T2` (`id`,`t1id`) VALUES (NULL,@lastID);
вторая вставка c id=100:
Код:
INSERT INTO `T1` (`id`) VALUES (100);
SET @lastID := LAST_INSERT_ID();
INSERT INTO `T2` (`id`,`t1id`) VALUES (NULL,@lastID);
в T2 в обеих записях FK указывает на первую запись в T1
id2 | t1id
1 | 1
2 | 1
 
Последнее редактирование:

junior17

Новичок
Друзья это конечно не относится к данной теме, но как насчет того чтобы в mysql не использовать auto_increment или эмуляции последовательности, а для primary_key генерировать уникальный идентификатор самому в приложении?
 

junior17

Новичок
Ну учитывая особенность auto_increment в mysql (auto_increment = max(id)), если в обычных CRUD сайтах это не такая уж проблема, то в более серьезных проектах вряд ли буду использовать. Эмуляция SEQUENCE вообще больше похожа на костыль
 
Последнее редактирование:

Adelf

Administrator
Команда форума
Друзья это конечно не относится к данной теме, но как насчет того чтобы в mysql не использовать auto_increment или эмуляции последовательности, а для primary_key генерировать уникальный идентификатор самому в приложении?
можно генерить guid. числовой генерить сложно.
 

c0dex

web.dev 2002-...
Команда форума
Партнер клуба
@junior17, уже пишешь серьезные проекты? Можно посмотреть?
 

Вурдалак

Продвинутый новичок
@Вурдалак, там речь про "specific task of generating a unique identifier", ни слова про sequence.
Это и есть sequence.
Ну если ты читаешь мануал как Библию, то вот тебе другая ссылка: https://dev.mysql.com/doc/refman/5.7/en/information-functions.html#function_last-insert-id
f expr is given as an argument to LAST_INSERT_ID(), the value of the argument is returned by the function and is remembered as the next value to be returned by LAST_INSERT_ID(). This can be used to simulate sequences:
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
автоинкремент - это один из множества способов генерировать уникальный идентификатор или работать с возрастающей последовательностью, и он создает некоторые сложности

@junior17, используй UUID, для mysql есть стандартные UDF для работы с UUID, а в постгресе нативная поддержка - специальный тип данных
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
это уже не средства mysql ;-) это стороннее приложение формирует запрос по своей логике, но можно через UDF
 
Сверху