tl;dr
Ora in Postgres 10, specifica GENERATED BY DEFAULT AS IDENTITY
secondo lo standard SQL.
create table tower
(
npages integer,
ifnds integer,
ifnid integer,
name varchar(20),
towid integer GENERATED BY DEFAULT AS IDENTITY -- per SQL standard
)
Colonna identità
Postgres 10 ora supporta il concetto di colonna identità e utilizza la sintassi SQL standard. Anche se non sono un esperto di MS SQL Server, credo che questo nuovo supporto standard sia equivalente.
GENERATED … AS IDENTITY
Il GENERATED … AS IDENTITY
comando utilizzato durante CREATE TABLE
crea una sequenza implicita. La creazione, la denominazione, le autorizzazioni e l'eliminazione di quella sequenza sono trasparenti per te, a differenza di SERIAL
. Molto intuitivo ora. Se concedi un'autorizzazione all'uso alla tabella, ottengono l'autorizzazione per la sequenza. Se si elimina la tabella, la sequenza viene eliminata automaticamente.
Due versioni della sintassi standard. La differenza conta solo se si passa un valore piuttosto che lasciare che un valore venga generato. In genere, le persone fanno sempre affidamento sul valore generato, quindi normalmente utilizzeresti semplicemente la prima versione, GENERATED BY DEFAULT AS IDENTITY
.
GENERATED BY DEFAULT AS IDENTITY
- Genera un valore a meno che non sia
INSERT
comando fornisce un valore.
- Genera un valore a meno che non sia
GENERATED ALWAYS AS IDENTITY
- Ignora qualsiasi valore fornito da
INSERT
a meno che non si specifichiOVERRIDING SYSTEM VALUE
- Ignora qualsiasi valore fornito da
Vedi CREATE TABLE
pagina per la documentazione.
Leggi questa pagina interessante
di Peter Eisentraut. Spiega alcuni strani problemi con SERIAL
. Nessun problema di questo tipo con la nuova funzione della colonna identità. Quindi non c'è motivo di usare SERIAL
più, nessun aspetto negativo, solo vantaggi; SERIAL
è soppiantato da GENERATED … AS IDENTITY
.
Si noti che una colonna Identity non è necessariamente una chiave primaria e non viene indicizzata automaticamente. Quindi devi ancora specificare PRIMARY KEY
esplicitamente se questa è la tua intenzione (come sarebbe il caso tipico).
CREATE TABLE person_ (
id_
INTEGER
GENERATED BY DEFAULT AS IDENTITY -- Replaces SERIAL. Implicitly creates a SEQUENCE, specified as DEFAULT.
PRIMARY KEY -- Creates index. Specifies UNIQUE. Marks column for relationships.
,
name_
VARCHAR( 80 )
) ;
L'intenzione è che i dettagli di implementazione interna ti siano nascosti. Non c'è bisogno che tu conosca il nome della sequenza che viene generata sotto le coperte. Ad esempio, puoi azzerare il contatore tramite la colonna senza conoscere la sequenza sottostante.
ALTER TABLE person_
ALTER COLUMN id_
RESTART WITH 1000 -- Reset sequence implicitly, without a name.
;
Specificare l'identità in modo implicito:
- Segna la colonna
NOT NULL
- Crea una sequenza
- Il tipo di sequenza corrisponde alla colonna ( 32 bit 64 bit ecc. )
- Lega la sequenza alla colonna
- Eredita le autorizzazioni
- Cascate in caduta
- Resta legato alla colonna anche se la colonna è stata rinominata
- Specifica la sequenza come origine dei valori predefiniti per quella colonna
La colonna Identity può assumere le stesse opzioni di CREATE SEQUENCE
:
START WITH start
MINVALUE minvalue
|NO MINVALUE
MAXVALUE maxvalue
|NO MAXVALUE
INCREMENT [ BY ] increment
CYCLE
|NO CYCLE
CACHE
cacheOWNED BY NONE
(per me non ha senso specificare la proprietà per la colonna identità poiché la proprietà viene gestita automaticamente)
Stupido esempio di opzioni:
id_ INTEGER
GENERATED BY DEFAULT AS IDENTITY (
START WITH 200
MINVALUE 100
MAXVALUE 205
CYCLE
INCREMENT BY 3
) PRIMARY KEY
Aggiunta di 4 righe: