Сохраняет ли Postgres порядок вставки записей?

19

Например, когда я использую запрос, который возвращает идентификаторы записей

INSERT INTO projects(name)
VALUES (name1), (name2), (name3) returning id;

Который производит продукцию:

1
2
3

Будут ли эти идентификаторы указывать на соответствующие вставленные значения?

1 -> name1
2 -> name2
3 -> name3
Сергей
источник
4
Помимо фактического ответа (который я считаю отрицательным), вы не должны полагаться ни на какой другой порядок, кроме того, который вы указали в своих запросах.
Дезсо

Ответы:

17

Ответ для этого простого случая - Да . Строки вставляются в указанном порядке в VALUESвыражении. И если ваш idстолбец является serialтипом, значения из базовой последовательности будут выбираться в этом порядке.

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

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

В таблице базы данных нет «естественного» порядка. Хотя физический порядок строк (который отражен в системном столбцеctid ) изначально будет соответствовать их вставленному порядку, он может измениться в любое время. UPDATE, DELETE, VACUUMИ другие команды могут изменить физический порядок строк. Но сгенерированные значения для idстабильны и никак не связаны с этим, конечно.

Эрвин Брандштеттер
источник
Я думаю, что Сергей больше обращался к вопросу, будет ли первая строка всегда получать id = 1, вторая id = 2 и третья id = 3 - не фактический «порядок» или строки
a_horse_with_no_name
@a_horse_with_no_name: Чтобы ответить на это : это будет иметь место со вновь созданным serialстолбцом - в идеале в той же транзакции.
Эрвин Брандштеттер,
Если вопрос «будет ли идентификатор name3 всегда больше, чем name1», будет ли он всегда правильным? (Что касается вашего второго абзаца)
Лулалала
@lulalala: не обязательно для более сложных запросов с объединениями и WHEREусловиями. Хотя я не могу придумать простых WHEREусловий, которые могли бы изменить порядок строк, объединения, безусловно, могут это сделать.
Эрвин Брандштеттер
3

Ответ Эрвина Брандштеттера может быть неверным в определенном случае.

Мы сделали, INSERT INTO ... SELECT bar,baz FROM foo ORDER BY bar и мы видим, что SELECT ctid,* FROM foo показывает, что физическое упорядочение строк в таблице не точно соответствует порядку вставки, кажется, немного растерялся. Обратите внимание, что в нашей таблице есть столбец jsonb с сильно меняющимся размером данных. Экспериментальное усечение данных jsonb во время вставки привело к правильному порядку вставки.

user2052675
источник
3
Как отметил @Erwin в первом предложении , он говорит «да» только в этом конкретном случае, упомянутом в вопросе. Как сказал @deszo в своем комментарии , никогда не полагайтесь на порядок «вставки»; вы всегда должны указывать порядок в операторе выбора, если вы полагаетесь на этот порядок для каких-либо целей.
Макс Вернон