Является ли концептуально правильным делать SELECT MAX (id) и т.д. Для поиска последней вставленной строки?

Я просматривал модуль Drupal, когда нашел этот шаблон для получения идентификатора последней строки:

SELECT MAX(id) FROM ... WHERE ...

где id - это поле, работающее обычным способом автоинкремента.

Является ли это концептуально правильным? Есть ли ситуация, когда этот шаблон не будет работать в среде MySQL/PostgreSQL?

Edit:

Спасибо за отличные комментарии и ответы!

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

Ответ 1

Это кажется субъективным, но я бы сказал, нет, это не концептуально правильно, потому что:

  • вам нужна последняя вставленная строка
  • но ваш запрос показывает максимальное значение id

Да, существует некоторая взаимосвязь между максимальным id и самой последней вставкой, но учтите следующее:

  • что, если последняя вставленная строка была удалена?

Ответ на MySQL: вы получаете разные результаты. Обратите внимание, что для этого не требуется многопоточность или несколько процессов. Это потому, что они две разные вещи (которые, по общему признанию, часто могут давать одинаковые результаты).

select max(id) from <tablename>

vs

select last_insert_id()

(Угадайте, какой из них прав.)


@Dems указал, что ОП неоднозначно. Я уточню свой основной момент:

Мы говорим о трех разных фрагментах информации:

  • максимальное значение id
  • id самой последней строки, специфичной для сеанса
  • id строки, которая недавно вставлена ​​в таблицу (независимо от сеанса)

Опасно то, что иногда запрос на один дает правильный ответ для другого - , но не всегда.

Ответ 2

выберите max (id), будет гарантировано только получение записи с наивысшим идентификатором. это может быть необязательно запись LAST, вставленная в таблицу. Помните, что операции DB могут выполняться параллельно. Вы можете вставить запись и получить идентификатор № 5. Но к тому времени, когда вы обойдетесь с select MAX(id), кто-то другой может добавить другую запись, и теперь max действительно # 6 вместо этого.

Кроме того, вы не можете использовать его для прогнозирования того, каким должен быть следующий назначенный идентификатор. Рассмотрим случай, когда некоторые вставки выполняются в транзакции. Последняя зафиксированная запись в БД снова # 5, затем выполняются 3 вставки (# 6, # 7, # 8), а затем они откат. Следующая вставка, которая будет выполнена, будет фактически # 9, а не # 6 снова - mysql не перерабатывает идентификационные номера из неудачных транзакций. И нет никакой гарантии, что вы тоже получите №9 - какой-то другой сеанс мог бы сделать вставку, прежде чем вы ее обходите, так что ваша четвертая вставка может быть # 10 или # 10 000 000 вместо.

Ответ 4

В MySQL вы можете просто использовать last_insert_id(), который более гарантированно работает.

Ответ 5

Это зависит от предложения WHERE и того, как приложение вставляется в эту таблицу. SELECT max(ID) FROM table всегда будет возвращать самый большой идентификатор во время выполнения запроса. Предполагая, что идентификатор является первичным ключом auto_increment, тогда он вернет самую последнюю строку. Однако в многопоточных средах, таких как веб-серверы, это может быть не идентификатор, который вы ожидаете, поскольку другой процесс может быть вставлен в эту таблицу. Например, если ваш PHP-код вставляется в таблицу, то select max(id) ожидает, что эта строка только что вставлена, это может не сработать, потому что другой процесс, возможно, вставил другую строку после вашей вставки и до того, как вы сделали свой select max.

Если идентификатор является первичным ключом auto_increment (mysql), то лучше выбрать MySql last_insert_id() или PHP mysql_insert_id(). Но опять же, не зная таблицы, предложения WHERE или того, что Drupal ожидает от этого запроса, невозможно сказать, делает ли Drupal "неправильное".

Ответ 6

Прочтите следующее: Директива 595

Epic не доверяет MAX (id), он терпит неудачу.

Ответ 7

PostgreSQL вам нужно иметь дело с sequences, поэтому все зависит от того, как настроен он

Ответ 8

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