PostgreSQL
 sql >> Database >  >> RDS >> PostgreSQL

Come creare l'equivalente di una colonna di identità di SQL Server in Postgres

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.
  • GENERATED ALWAYS AS IDENTITY
    • Ignora qualsiasi valore fornito da INSERT a meno che non si specifichi OVERRIDING SYSTEM VALUE

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 cache
  • OWNED 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: