PostgreSQL
 sql >> Datenbank >  >> RDS >> PostgreSQL

So erstellen Sie das Äquivalent einer SQL Server-Identitätsspalte in Postgres

tl;dr

Geben Sie jetzt in Postgres 10 GENERATED BY DEFAULT AS IDENTITY an nach dem SQL-Standard.

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

Identitätsspalte

Postgres 10 unterstützt jetzt das Konzept der Identitätsspalte , und verwendet die Standard-SQL-Syntax. Obwohl ich kein Experte für MS SQL Server bin, glaube ich, dass diese neue Standardunterstützung gleichwertig ist.

GENERATED … AS IDENTITY

Der GENERATED … AS IDENTITY Befehl, der während CREATE TABLE verwendet wird erzeugt eine implizite Sequenz. Anders als bei SERIAL ist das Erstellen, Benennen, Berechtigen und Löschen dieser Sequenz für Sie transparent . Jetzt sehr intuitiv. Wenn Sie der Tabelle eine Nutzungserlaubnis erteilen, erhalten sie die Erlaubnis für die Sequenz. Wenn Sie die Tabelle löschen, wird die Sequenz automatisch gelöscht.

Zwei Varianten der Standard-Syntax. Der Unterschied spielt nur eine Rolle, wenn Sie einen Wert übergeben, anstatt einen Wert generieren zu lassen. Normalerweise verlassen sich die Leute immer auf den generierten Wert, also würden Sie normalerweise einfach die erste Version verwenden, GENERATED BY DEFAULT AS IDENTITY .

  • GENERATED BY DEFAULT AS IDENTITY
    • Erzeugt einen Wert, sofern nicht INSERT Befehl liefert einen Wert.
  • GENERATED ALWAYS AS IDENTITY
    • Ignoriert jeden Wert, der von INSERT bereitgestellt wird es sei denn, Sie geben OVERRIDING SYSTEM VALUE an

Siehe CREATE TABLE Seite für die Dokumentation.

Lesen Sie diese interessante Seite von Peter Eisentraut. Er erklärt einige seltsame Probleme mit SERIAL . Keine derartigen Probleme mit der neuen Identitätsspaltenfunktion. Es gibt also keinen Grund, SERIAL zu verwenden mehr, keine Nachteile, nur Vorteile; SERIAL wird durch GENERATED … AS IDENTITY ersetzt .

Beachten Sie, dass eine Identitätsspalte nicht unbedingt ein Primärschlüssel ist und nicht automatisch indiziert wird. Sie müssen also noch PRIMARY KEY angeben ausdrücklich, wenn dies Ihre Absicht ist (was normalerweise der Fall wäre).

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 )

) ;

Die internen Implementierungsdetails sollen Ihnen verborgen bleiben. Sie brauchen den Namen der Sequenz, die im Verborgenen generiert wird, nicht zu kennen. Beispielsweise können Sie den Zähler über die Spalte zurücksetzen, ohne die zugrunde liegende Sequenz zu kennen.

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

Identität implizit angeben:

  • Markiert die Spalte NOT NULL
  • Erzeugt eine Sequenz
    • Der Sequenztyp entspricht der Spalte ( 32-Bit 64-Bit usw. )
  • Verknüpft die Sequenz mit der Spalte
    • Erbt Berechtigungen
    • Kaskaden fallen
    • Bleibt an die Spalte gebunden, auch wenn die Spalte umbenannt wird
  • Gibt die Sequenz als Quelle der Standardwerte für diese Spalte an

Die Identitätsspalte kann dieselben Optionen annehmen wie CREATE SEQUENCE :

  • START WITH start
  • MINVALUE minvalue | NO MINVALUE
  • MAXVALUE maxvalue | NO MAXVALUE
  • INCREMENT [ BY ] increment
  • CYCLE | NO CYCLE
  • CACHE zwischenspeichern
  • OWNED BY NONE
    (Die Angabe des Eigentums für die Identitätsspalte macht für mich keinen Sinn, da das Eigentum automatisch verwaltet wird)

Dummes Beispiel für Optionen:

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

Hinzufügen von 4 Zeilen: