O Postgres preserva a ordem de inserção dos registros?

19

Por exemplo, quando estou usando uma consulta que retorna IDs de registro

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

Quais produzem saída:

1
2
3

Esses IDs apontarão para os valores inseridos correspondentes?

1 -> name1
2 -> name2
3 -> name3
Sergey
fonte
4
A resposta real de lado (que eu acredito que não), você não deve confiar em nenhuma outra ordem além daquela especificada em suas consultas.
Dezso

Respostas:

17

A resposta para este caso simples é Sim . As linhas são inseridas na ordem fornecida noVALUES expressão. E se sua idcoluna for um serialtipo, os valores da sequência subjacente serão buscados nessa ordem.

Mas este é um detalhe de implementação e não há garantias. Em particular, o pedido não é necessariamente mantido em consultas mais complexas com WHEREcondições ou junções.

Você também pode obter intervalos ou outras linhas misturadas se tiver transações simultâneas gravando na mesma tabela ao mesmo tempo. Improvável, mas possível.

Não há ordem "natural" em uma tabela de banco de dados. Embora a ordem física das linhas (refletida na colunactid do sistema ) corresponda inicialmente à ordem inserida, isso pode mudar a qualquer momento. UPDATE, DELETE, VACUUME outros comandos pode mudar a ordem física das linhas. Mas os valores gerados para idsão estáveis ​​e de forma alguma conectados a isso, é claro.

Erwin Brandstetter
fonte
Eu acho que Sergey estava mais se referindo à questão de saber se a primeira linha sempre terá id = 1, a segunda id = 2 e a terceira id = 3 - não a "ordem" real ou as linhas
a_horse_with_no_name
@a_horse_with_no_name: Para responder a isso : será o caso de uma serialcoluna recém-criada - idealmente na mesma transação.
Erwin Brandstetter
Se a pergunta for "o ID do nome3 sempre será maior que o do nome1", estaria sempre correto? (Em relação ao seu segundo parágrafo)
lulalala
@lulalala: Não necessariamente para consultas mais complexas com junções e WHEREcondições. Embora eu não consiga pensar em WHEREcondições simples que alterariam a ordem das linhas, as junções certamente podem fazer isso.
Erwin Brandstetter 02/01
3

A resposta de Erwin Brandstetter pode não estar correta em um determinado caso.

Fizemos um INSERT INTO ... SELECT bar,baz FROM foo ORDER BY bar e vemos que isso SELECT ctid,* FROM foo mostra que a ordem física das linhas na tabela não corresponde exatamente à ordem de inserção, parece um pouco embaralhada. Observe que nossa tabela possui uma coluna jsonb com tamanho de dados altamente variável. O truncamento experimental dos dados jsonb durante a inserção fez com que a ordem da inserção estivesse correta.

user2052675
fonte
3
Como @Erwin apontou na primeira frase , ele está apenas dizendo "sim" nessa instância específica mencionada na pergunta. Como o @deszo disse em seu comentário , nunca confie na ordem "inserir"; você sempre deve especificar o pedido na instrução select se estiver contando com esse pedido para qualquer finalidade.
Max Vernon