sql >> Databasteknik >  >> RDS >> PostgreSQL

Hur man skapar motsvarigheten till en SQL Servers identitetskolumn i Postgres

tl;dr

Nu i Postgres 10, ange GENERERAD AV DEFAULT SOM IDENTITET enligt SQL-standarden.

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

Kolumnen Identitet

Postgres 10 stöder nu konceptet identitetskolumnen , och använder standard SQL-syntax. Även om jag inte är någon expert på MS SQL Server, tror jag att detta nya standardstöd är likvärdigt.

GENERERAD … SOM IDENTITET

Den GENERERADE … SOM IDENTITET kommandot som används under CREATE TABLE skapar en implicit sekvens. Skapandet, namngivningen, behörigheterna och släppandet av den sekvensen är transparent för dig, till skillnad från med SERIAL . Väldigt intuitivt nu. Om du ger en användningsbehörighet till tabellen får de behörighet för sekvensen. Om du släpper tabellen släpps sekvensen automatiskt.

Två smaker av standardsyntaxen. Skillnaden spelar bara roll om du skickar ett värde istället för att låta ett värde genereras. Vanligtvis litar folk alltid på det genererade värdet, så normalt skulle du helt enkelt använda den första versionen, GENERERAD AV DEFAULT SOM IDENTITET .

  • GENERERAD AV STANDARD SOM IDENTITET
    • Genererar ett värde om inte INSERT kommandot ger ett värde.
  • GENERERAD ALLTID SOM IDENTITET
    • Ignorerar alla värden som tillhandahålls av INSERT om du inte anger ÖVERSKRIDNING AV SYSTEMVÄRDE

Se SKAPA TABELL sida för dokumentation.

Läs denna intressanta sida av Peter Eisentraut. Han förklarar några konstiga problem med SERIAL . Inga sådana problem med den nya identitetskolumnfunktionen. Så det finns ingen anledning att använda SERIAL längre, inga nackdelar, bara uppsidor; SERIAL ersätts av GENERAT … SOM IDENTITET .

Observera att en identitetskolumn inte nödvändigtvis är en primärnyckel och inte automatiskt indexeras. Så du måste fortfarande ange PRIMARY KEY uttryckligen om det är din avsikt (som vanligtvis är fallet).

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 )

) ;

Avsikten är att de interna implementeringsdetaljerna ska döljas för dig. Du behöver inte veta namnet på sekvensen som genereras under täcket. Du kan till exempel nollställa räknaren via kolumnen utan att känna till den underliggande sekvensen.

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

Ange identitet implicit:

  • Markerar kolumnen NOT NULL
  • Skapar en sekvens
    • Typen av sekvens matchar kolumnen ( 32-bitars 64-bitars etc. )
  • Kopplar sekvensen till kolumnen
    • Ärver behörigheter
    • Kaskader faller
    • Förblir knuten till kolumnen även om kolumnen bytt namn
  • Anger sekvensen som källa för standardvärden för den kolumnen

Identitetskolumnen kan ha samma alternativ som SKAPA SEKVENS :

  • STARTA MED start
  • MINVALUE minvärde | INGET MINVÄRDE
  • MAXVALUE maxvärde | INGEN MAXVÄRDE
  • ÖKNING [ MED ] ökning
  • CYKLA | INGEN CYKEL
  • CACHE cache
  • ÄGES AV INGEN
    ( att ange äganderätt för kolumnen identitet är meningslöst för mig eftersom ägande hanteras automatiskt )

Dumt exempel på alternativ:

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

Lägger till 4 rader:



  1. Ersätter sekvens med slumptal

  2. gör den inkrementerade kolumnen b-trädets index på kolumnen obalanserat?

  3. Mysql Skapa databas med specialtecken i namnet

  4. Rails och MySQL-syntaxfel med flera SQL-satser i ett exekveringsblock