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

Sådan opretter du det, der svarer til en SQL Servers identitetskolonne i Postgres

tl;dr

Nu i Postgres 10, angiv GENERATED BY DEFAULT AS IDENTITY i henhold til SQL-standarden.

create table tower 
(
  npages integer, 
  ifnds integer, 
  ifnid integer, 
  name varchar(20), 
  towid integer GENERATED BY DEFAULT AS IDENTITY    -- per SQL standard
)

Identitetskolonnen

Postgres 10 understøtter nu konceptet identitetskolonnen , og bruger standard SQL-syntaks. Selvom jeg ikke er ekspert i MS SQL Server, tror jeg, at denne nye standardsupport er ækvivalent.

GENERERET … SOM IDENTITET

Den GENERERET … SOM IDENTITET kommando brugt under CREATE TABLE skaber en implicit sekvens. Oprettelse, navngivning, tilladelser og sletning af den sekvens er gennemsigtig for dig, i modsætning til med SERIAL . Meget intuitiv nu. Hvis du giver en brugstilladelse til tabellen, får de tilladelse til sekvensen. Hvis du dropper tabellen, slettes sekvensen automatisk.

To varianter af standardsyntaksen. Forskellen har kun betydning, hvis du sender en værdi i stedet for at lade en værdi genereres. Typisk stoler folk altid på den genererede værdi, så normalt ville du blot bruge den første version, GENERERET AF STANDARD SOM IDENTITET .

  • GENERERET AF STANDARD SOM IDENTITET
    • Genererer en værdi, medmindre INSERT kommandoen giver en værdi.
  • GENERERET ALTID SOM IDENTITET
    • Ignorerer enhver værdi leveret af INSERT medmindre du angiver OVERORDNING AF SYSTEMVÆRDI

Se OPRET TABEL side for dokumentation.

Læs denne interessante side af Peter Eisentraut. Han forklarer nogle mærkelige problemer med SERIAL . Ingen sådanne problemer med den nye identitetskolonnefunktion. Så der er ingen grund til at bruge SERIAL længere, ingen ulemper, kun fordele; SERIAL er erstattet af GENERATED … AS IDENTITY .

Bemærk, at en identitetskolonne ikke nødvendigvis er en primær nøgle og ikke automatisk indekseres. Så du skal stadig angive PRIMARY KEY udtrykkeligt, hvis det er din hensigt (som det typisk ville være tilfældet).

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 )

) ;

Hensigten er, at de interne implementeringsdetaljer skal være skjult for dig. Du behøver ikke at kende navnet på den sekvens, der genereres under coveret. For eksempel kan du nulstille tælleren via kolonnen uden at kende den underliggende rækkefølge.

ALTER TABLE person_ 
    ALTER COLUMN id_ 
    RESTART WITH 1000      -- Reset sequence implicitly, without a name.
;

Angivelse af identitet implicit:

  • Mærker kolonne IKKE NULL
  • Opretter en sekvens
    • Typen af ​​sekvens matcher kolonnen (32-bit 64-bit osv.)
  • Knyter sekvensen til kolonnen
    • Arver tilladelser
    • Kaskader falder
    • Forbliver knyttet til kolonnen, selvom kolonnen omdøbes
  • Specificerer sekvensen som kilde til standardværdier for den pågældende kolonne

Identitetskolonnen kan have de samme muligheder som CREATE SEQUENCE :

  • START MED start
  • MINVALUE minværdi | INGEN MINVÆRDI
  • MAXVALUE maxvalue | INGEN MAKSVÆRDI
  • TØG [ BY ] stigning
  • CYKLUS | INGEN CYKUS
  • CACHE cache
  • EJES AF INGEN
    (det giver ingen mening for mig at angive ejerskab for kolonnen identitet, da ejerskab administreres automatisk)

Dumt eksempel på muligheder:

id_ INTEGER 
GENERATED BY DEFAULT AS IDENTITY ( 
    START WITH 200 
    MINVALUE 100 
    MAXVALUE 205 
    CYCLE 
    INCREMENT BY 3 
) PRIMARY KEY

Tilføjelse af 4 rækker:



  1. PHP, SQL begrænse forespørgsel efter php variabel

  2. Oracle MERGE:kun NOT MATCHED udløses

  3. Hvordan reparerer jeg en InnoDB-tabel?

  4. Hvordan udfyldes fremmednøgleværdier i en Hibernate + Spring JPA-konfiguration, når overordnede/underordnede objekter bevares på samme tid?