serial
är den "gamla" implementeringen av automatiskt genererade unika värden som har varit en del av Postgres i evigheter. Det är dock inte en del av SQL-standarden.
För att vara mer kompatibel med SQL-standarden introducerade Postgres 10 syntaxen med generated as identity
.
Den underliggande implementeringen är fortfarande baserad på en sekvens, definitionen överensstämmer nu med SQL-standarden. En sak som denna nya syntax tillåter är att förhindra en oavsiktlig åsidosättning av värdet.
Tänk på följande tabeller:
create table t1 (id serial primary key);
create table t2 (id integer primary key generated always as identity);
Nu när du kör:
insert into t1 (id) values (1);
Den underliggande sekvensen och värdena i tabellen är inte längre synkroniserade. Om du kör en annan
insert into t1 default_values;
Du kommer att få ett felmeddelande eftersom sekvensen inte avancerades av den första infogningen och nu försöker infoga värdet 1
på nytt.
Med den andra tabellen däremot,
insert into t2 (id) values (1);
Resultat i:
ERROR: cannot insert into column "id" Detail: Column "id" is an identity column defined as GENERATED ALWAYS.
Så du kan av misstag "glömma" sekvensanvändningen. Du kan fortfarande tvinga fram detta genom att använda override system value
alternativ:
insert into t2 (id) overriding system value values (1);
vilket fortfarande lämnar dig med en sekvens som inte är synkroniserad med värdena i tabellen, men du blev åtminstone medveten om det.
Det rekommenderas att använda den nya identitetssyntaxen snarare än seriell