Альтернатива "PDO :: lastInsertId" / "mysql_insert_id"

Я всегда слышу, что использование lastInsertId (или mysql_insert_id (), если вы не используете PDO) - зло. В случае триггеров это очевидно, потому что он может вернуть что-то, что совершенно не является последним идентификатором, созданным вашим INSERT.

$DB->exec("INSERT INTO example (column1) VALUES ('test')");
// Usually returns your newly created ID.
// However when a TRIGGER inserts into another table with auto-increment:
// -> Returns newly created ID of trigger's INSERT
$id = $DB->lastInsertId();

Какая альтернатива?

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
6
0
12 247
6
Перейти к ответу Данный вопрос помечен как решенный

Ответы 6

Это не сложно и неэффективно, но если данные, которые вы вставили, включают уникальные поля, тогда SELECT, очевидно, может дать то, что вам нужно.

Например:

INSERT INTO example (column1) VALUES ('test');
SELECT id FROM example WHERE column1 = 'test';

Очевидно;) - Но тоже, очевидно, довольно некрасиво;)

BlaM 14.11.2008 15:31

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

Очевидно, тоже работает, но блокировка IMHO еще более зла в высокопроизводительных веб-приложениях ...

BlaM 14.11.2008 16:03

ИМХО это считается «злом», потому что вряд ли в какой-либо другой базе данных SQL (если таковая имеется) он есть.

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

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

BlaM 14.11.2008 16:16
Ответ принят как подходящий

Если вы идете по маршруту ADOdb (http://adodb.sourceforge.net/), вы можете создать идентификатор вставки перед рукой и явно указать идентификатор при вставке. Это может быть реализовано переносимо (ADOdb поддерживает множество различных баз данных ...) и гарантирует, что вы используете правильный идентификатор вставки.

Тип данных PostgreSQL SERIAL аналогичен, за исключением того, что он для каждой таблицы / последовательности, вы указываете таблицу / последовательность, для которой требуется последний идентификатор вставки, когда вы ее запрашиваете.

Смотрится довольно интересно. Как этот прием влияет на производительность?

BlaM 14.11.2008 18:47

Да, но что делать, если вы застряли с PDO?

Elijah 24.02.2010 21:47

Вы можете написать свой собственный код, чтобы делать то же самое, что и ADOdb, за исключением использования PDO. По сути, вы получаете отдельную таблицу для хранения последовательности, которую вы ЗАПИВАЕТЕ БЛОКИРОВАТЬ перед увеличением значения последовательности при получении нового идентификатора.

Keith Palmer Jr. 25.02.2010 16:27

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

Keith Palmer Jr. 25.02.2010 16:29

Одна альтернатива - использовать вместо этого последовательности, поэтому вы сами создаете идентификатор, прежде чем делать вставку.

К сожалению, они не поддерживаются в MySQL, но библиотеки, такие как Adodb, могут имитировать их, используя другую таблицу. Я думаю, однако, что сама эмуляция будет использовать lastInsertId () или эквивалент ... но, по крайней мере, у вас меньше шансов иметь триггер в таблице, которая используется исключительно для последовательности

Вы можете попробовать это:

$sql = "SELECT id FROM files ORDER BY id DESC LIMIT 1";
$PS = $DB -> prepare($sql);
$PS -> execute();
$result = $PS -> fetch();

Это не альтернатива в условиях высокой посещаемости. Вы будете постоянно получать неправильные идентификаторы.

BlaM 02.08.2012 14:07

Другие вопросы по теме