Чи зберігає Postgres порядок вставки записів?


19

Наприклад, коли я використовую запит, який повертає ідентифікатори запису

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

Які виробляють вихід:

1
2
3

Чи вкаже цей ідентифікатор на відповідні вставлені значення?

1 -> name1
2 -> name2
3 -> name3

4
Фактична відповідь убік (яка, на мою думку, є ні), ви не повинні покладатися на будь-яке інше замовлення, крім того, яке ви вказали у своїх запитах.
dezso

Відповіді:


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

@lulalala: Не обов'язково для більш складних запитів з об'єднаннями та WHEREумовами. Хоча я не можу придумати прості WHEREумови, які змінювали б порядок рядків, приєднання, безумовно, може це зробити.
Ервін Брандстетер

3

Відповідь Ервіна Брандстеттера в певному випадку може бути невірною.

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


3
Як зазначив @Erwin у першому реченні , він говорить лише «так» у тому конкретному випадку, про який йдеться у запитанні. Як сказав @deszo у своєму коментарі , ніколи не покладайтеся на замовлення "вставити"; Ви завжди повинні вказувати порядок у операторі select, якщо ви покладаєтесь на це замовлення з будь-якою метою.
Макс Вернон
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.