Informix: cosa succede quando si elimina una riga con chiave primaria serial / serial8?
Domanda
Ho avuto una domanda veloce sui tipi di dati seriali usati sulla chiave primaria su db di informix.
Se elimino una riga, la chiave seriale continuerà a contare o si adeguerà per le righe che sono state eliminate?
Quindi se la riga corrente è il numero seriale 5, elimino il numero riga con il numero seriale 3, il valore successivo sarà 6 e continuerò a continuare? Il numero seriale 3 che è stato eliminato per sempre e perso non può essere riutilizzato?
Soluzione
Il contatore utilizzato da SERIAL, SERIAL8 o BIGSERIAL aumenta monotonicamente fino a quando non si avvolge. I valori eliminati vengono semplicemente eliminati. Se si inserisce un valore letterale maggiore del contatore, il contatore viene regolato in modo che il valore inserito successivo sia uno maggiore:
CREATE TABLE s (s SERIAL(2) NOT NULL PRIMARY KEY, v VARCHAR(20) NOT NULL);
INSERT INTO s(s,v) VALUES(0, "Row 2");
INSERT INTO s(s,v) VALUES(0, "Row 3");
INSERT INTO s(s,v) VALUES(0, "Row 4");
INSERT INTO s(s,v) VALUES(0, "Row 5");
DELETE FROM s WHERE s = 3;
INSERT INTO s(s,v) VALUES(0, "Row 6");
INSERT INTO s(s,v) VALUES(8, "Row 8"); -- Skip 7
INSERT INTO s(s,v) VALUES(0, "Row 9");
SELECT * FROM s ORDER BY s;
Questo genera i risultati:
2 Row 2
4 Row 4
5 Row 5
6 Row 6
8 Row 8
9 Row 9
Tutti i tipi si comportano in modo simile. Se si raggiunge il massimo (2 ^ 32-1 per SERIAL, 2 ^ 63-1 per SERIAL8 e BIGSERIAL), il contatore torna a zero, ma è possibile che si verifichino problemi con riutilizzo di spazi non vuoti e la chiave primaria rifiutata righe duplicate. In generale, evitare di avvolgerli. (Ci vuole un po 'di tempo per farli concludere, in particolare i contatori a 64 bit.)
Tieni presente che puoi inserire manualmente un valore "mancante", ad esempio 3 o 7. Tuttavia, IDS non lo farà per te.
@iQ chiesto:
Quindi Informix riutilizza automaticamente i valori seriali non utilizzati o eliminati quando si avvolge?
Non proprio. Il valore torna a 1; se esiste la riga con valore 1, l'inserimento non riesce; in caso contrario, ha successo; in entrambi i casi, il tentativo successivo tenterà 2. Per illustrare, continuando da dove è stato interrotto l'ultimo esempio:
INSERT INTO s(s,v) VALUES(2147483647, "Row 2,147,483,647");
INSERT INTO s(s,v) VALUES(0, "Row next") { 1 - Pass };
INSERT INTO s(s,v) VALUES(0, "Row next + 1") { 2 - Fail };
INSERT INTO s(s,v) VALUES(0, "Row next + 2") { 3 - Pass };
INSERT INTO s(s,v) VALUES(0, "Row next + 3") { 4 - Fail };
SELECT * FROM s ORDER BY s;
Il risultato finale è:
1 Row next
2 Row 2
3 Row next + 2
4 Row 4
5 Row 5
6 Row 6
8 Row 8
9 Row 9
2147483647 Row 2,147,483,647
Chiaramente, i prossimi tre inserti fallirebbero, uno avrebbe successo, altri due avrebbero fallito, e poi avrebbero avuto successo per il prossimo paio di miliardi di inserti.