Pdo, postgresql, lastinsertid

Фанат

oncle terrible
Команда форума

Adelf

Administrator
Команда форума
nextval

Advance the sequence object to its next value and return that value. This is done atomically: even if multiple sessions execute nextval concurrently, each will safely receive a distinct sequence value.
 

флоппик

promotor fidei
Команда форума
Партнер клуба
Я в постгресе не разбираюсь, но нигде не увидел по ссылке, что nextval is connection based
поэтому вопрос остается в силе
Вообще, надо сказать, что подход с nexval он как раз таки каноничный, и используется в том числе и в оракле, например, а автоинкремент как раз таки исторически сложившийся персональный мускульный костыль для эмуляции секвенсов.
 

флоппик

promotor fidei
Команда форума
Партнер клуба
Не знаю как в постгре, кстати, а в оракле еще можно было запросить range из секвенса per connection, что дает возможность жахнуть все записи в один/смежные блоки в фс/на диске, что существенно влияет на скорость записи (ну и чтения, конеэшг).
 

флоппик

promotor fidei
Команда форума
Партнер клуба
А чо, в 2018 кто-то до сих пор пользуется AUTO_INCREMENT? Вам не больно?
Ну если уж быть совсем честным, автоинкремент 80% задач секвенсирования данных в табличках в веб-разработке покрывает, в принципе. Но в целом, 95% мускула создано из костылей и хаков, и автоинкремент далеко не самое худшее из них.
 

fixxxer

К.О.
Партнер клуба
А чо, в 2018 кто-то до сих пор пользуется AUTO_INCREMENT?
Честно говоря, за последние лет 5 не видел ни одного проекта (кроме моих), где бы им не пользовались (вместе с anemic models). Всем норм, чо.

Это такая боль, которую осознаешь только когда понимаешь, как можно иначе. :)
 

junior17

Новичок
Друзья, так в чем профит вызывать сперва nextval, потом insert? Если можно простыми словами
 

fixxxer

К.О.
Партнер клуба
Ну, в первом приближении...
Знать ID заранее очень удобно, если ты пишешь объектно-ориентированные программы.

Если знаю заранее:
1) $id получили из nextval
2) $user = new User($id, $name); // создали объект в памяти
3) $userRepository->store($user); // записали его в базу

Если не знаю заранее ID - то надо как-то создать сущность без ID, потом только после сохранения в базу его присвоить... Это все усложняет, особенно если между (2) и (3) еще всякое там разное, когда надо бы знать id юзера, а его пока еще нет.
 

Adelf

Administrator
Команда форума
@fixxxer, тут самый важный момент, что сущность new User($id, $name) изначально консистентная. ее можно передать куда угодно и там не надо будет проверять, закинули ли ее уже в бд или нет. есть у нее id или нет. ->exists() или не ->exists().
если юзеру надо сразу добавить, например, роль, то можно тоже сразу создать и добавить его в юзерские роли. Ибо id юзера уже будет известен. На данном простом примере трудно понять профит. Но я пару раз уже напарывался на такое, что у нас автоинкремент а id очень хотелось бы получить пораньше.
 

fixxxer

К.О.
Партнер клуба
Ну он же просил простыми словами :)

Со спагетти-кодом типа
PHP:
$pdo = $dbh->prepare("INSERT INTO users (name) VALUES(?)");
$pdo->bindValue(1, $name);
$pdo->execute();
(а $name там наверняка прям из $_POST сотней строк выше) все равно будет непонятно, там-то разницы никакой не будет.
 

AnrDaemon

Продвинутый новичок
Вы ещё учитывайте, что в 99% применения PHP, новосозданную сущность просто некуда передавать, кроме как в базу. На чём, собственно, работа скрипта завершается.
 

Вурдалак

Продвинутый новичок
Друзья, так в чем профит вызывать сперва nextval, потом insert? Если можно простыми словами
У нас было на форуме обсуждение, вот примерные ссылки, конкретные цитаты лень приводить:
https://phpclub.ru/talk/threads/Выбор-framework.80801/page-5#post-731461
https://phpclub.ru/talk/threads/Выбор-framework.80801/page-4#post-731297
https://phpclub.ru/talk/threads/Не-работает-auto_increment.80857/

Если постараться дополнить то, что уже упомянул @fixxxer, то

1. В консистентной модели зачастую пишут события а-ля UserRegistered, EmployeeWasHired, etc., которые должны уже содержать id сущности; но до момента сохранения в костыльных реализациях с AUTO_INCREMENT это невозможно. Сюда же вообще можно отнести кучу всякой мелочи, что описал @Adelf, когда нам не хочется думать в каком порядке что нужно сохранять.
2. Зачастую полезно знать id сущности [задолго] до ее создания. Это может быть как асинхронная логика (передать id клиенту, поставить задачу в очередь), так и а-ля проверка на спам: проверяем контент до сохранения (если явный спам — отклоняем; если подозрительный — сохраняем id), а сохраненный id поможет в будущем вернуться к сущности и как-то ее заблокировать, если подозрения на спам подтвердятся (обычно такая логика бывает, если требуется некая «критическая» масса подозрительных объектов).
3. Более высокая детерминированность команд: если я регистрирую игрока RegisterPlayer { id: 42, name: "lifecoach" }, то я ожидаю ровно того, что я указал, т.е. я ожидаю, что будет зарегистрирован игрок с id 42, если он есть — будет явная ошибка. В случае же RegisterPlayer { name: "lifecoach" } повышается вероятность того, что будет тупо зарегистрирован второй игрок с таким же ником. Чем более детерминированная команда, тем проще с ней работать и тестировать: меньше сюрпризов.
4. Неожиданные сюрпризы от MySQL типа того, что по всей видимости были у автора в этом топике: «InnoDB uses the in-memory auto-increment counter as long as the server runs. When the server is stopped and restarted, InnoDB reinitializes the counter for each table for the first INSERT to the table, as described earlier.».

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

Вурдалак

Продвинутый новичок
Ну если уж быть совсем честным, автоинкремент 80% задач секвенсирования данных в табличках в веб-разработке покрывает, в принципе. Но в целом, 95% мускула создано из костылей и хаков, и автоинкремент далеко не самое худшее из них.
Ну, это значит, что у тебя 80% сущностей без событий, как минимум в том виде, в котором это делаю я (запись внутри сущности). У меня процент таких сущностей существенно меньше.
 

флоппик

promotor fidei
Команда форума
Партнер клуба
Ну, это значит, что у тебя 80% сущностей без событий, как минимум в том виде, в котором это делаю я (запись внутри сущности). У меня процент таких сущностей существенно меньше.
Меня как раз после оракла регулярно колет автоинкрементом ) Но ребятам вокруг норм.)
 

junior17

Новичок
Проблема с Auto_Increment (auto_increment = max(id)) только в mysql(innodb) или в postgre такая же история? Ведь мы создавая
SEQUENCE указываем INCREMENT BY 1. Тоже ведь тоже auto_increment?
 
Сверху