serial
é a implementação "antiga" de valores únicos gerados automaticamente que faz parte do Postgres há muito tempo. No entanto, isso não faz parte do padrão SQL. Para ser mais compatível com o padrão SQL, o Postgres 10 introduziu a sintaxe usando
generated as identity
. A implementação subjacente ainda é baseada em uma sequência, a definição agora está em conformidade com o padrão SQL. Uma coisa que essa nova sintaxe permite é evitar uma substituição acidental do valor.
Considere as seguintes tabelas:
create table t1 (id serial primary key);
create table t2 (id integer primary key generated always as identity);
Agora quando você executa:
insert into t1 (id) values (1);
A sequência subjacente e os valores na tabela não estão mais sincronizados. Se você executar outro
insert into t1 default_values;
Você receberá um erro porque a sequência não foi avançada pela primeira inserção e agora tenta inserir o valor
1
novamente. Com a segunda tabela, no entanto,
insert into t2 (id) values (1);
Resulta em:
ERROR: cannot insert into column "id" Detail: Column "id" is an identity column defined as GENERATED ALWAYS.
Assim, você pode acidentalmente "esquecer" o uso da sequência. Você ainda pode forçar isso, usando o
override system value
opção:insert into t2 (id) overriding system value values (1);
o que ainda deixa você com uma sequência que está fora de sincronia com os valores na tabela, mas pelo menos você estava ciente disso.
Recomenda-se usar a nova sintaxe de identidade em vez de serial