Postgres conserva l'ordine di inserimento dei record?


19

Ad esempio, quando utilizzo query che restituisce ID record

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

Che producono output:

1
2
3

Questo ID indicherà i corrispondenti valori inseriti?

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

4
La risposta effettiva a parte (che credo sia no) non si dovrebbe fare affidamento su un ordine diverso da quello specificato nelle domande.
dezso

Risposte:


17

La risposta per questo semplice caso è . Le righe vengono inserite nell'ordine indicato VALUESnell'espressione. E se la tua idcolonna è di serialtipo, i valori della sequenza sottostante verranno recuperati in quell'ordine.

Ma questo è un dettaglio di implementazione e non ci sono garanzie. In particolare, l'ordine non viene necessariamente mantenuto in query più complesse con WHEREcondizioni o join.

Potresti anche ottenere spazi vuoti o altre righe mescolate se hai transazioni simultanee che scrivono sulla stessa tabella allo stesso tempo. Improbabile, ma possibile.

Non esiste un ordine "naturale" in una tabella del database. Mentre l'ordine fisico delle righe (che si riflette nella colonna di sistemactid ) corrisponderà inizialmente al loro ordine inserito, che può cambiare in qualsiasi momento. UPDATE, DELETE, VACUUME altri comandi possono cambiare l'ordine fisico delle righe. Ma i valori generati per idsono stabili e non collegati in alcun modo a quello, ovviamente.


Penso che Sergey si riferisse maggiormente alla domanda se la prima riga otterrà sempre id = 1, il secondo id = 2 e il terzo id = 3 - non l'attuale "ordine" o le righe
a_horse_with_no_name

@a_horse_with_no_name: per rispondere a questo : sarà il caso di una serialcolonna appena creata , idealmente nella stessa transazione.
Erwin Brandstetter,

Se la domanda è "l'ID di name3 sarà sempre più grande di quello di name1", sarebbe sempre corretto? (Per quanto riguarda il tuo secondo paragrafo)
Lulalala,

@lulalala: non necessariamente per query più complesse con join e WHEREcondizioni. Anche se non riesco a pensare a WHEREcondizioni semplici che possano cambiare l'ordine delle righe, i join possono certamente farlo.
Erwin Brandstetter il

3

La risposta di Erwin Brandstetter potrebbe non essere corretta in un determinato caso.

INSERT INTO ... SELECT bar,baz FROM foo ORDER BY bar Ne abbiamo fatto uno e vediamo che SELECT ctid,* FROM foo mostra che l'ordinamento fisico delle righe nella tabella non corrisponde esattamente all'ordine di inserimento, sembra un po 'confuso. Nota che la nostra tabella ha una colonna jsonb con dimensioni dei dati molto variabili. Il troncamento sperimentale dei dati jsonb durante l'inserimento ha determinato che l'ordine di inserimento fosse corretto.


3
Come ha sottolineato @Erwin nella prima frase , sta solo dicendo "sì" in quella particolare singola istanza a cui fa riferimento la domanda. Come ha detto @deszo nel suo commento , non fare mai affidamento sull'ordine "insert"; dovresti sempre specificare l'ordine nell'istruzione select se ti affidi a quell'ordine per qualsiasi scopo.
Max Vernon,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.