PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

Comment créer l'équivalent de la colonne d'identité d'un serveur SQL dans Postgres

tl;dr

Maintenant dans Postgres 10, spécifiez GENERATED BY DEFAULT AS IDENTITY selon la norme SQL.

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

Colonne d'identité

Postgres 10 prend désormais en charge le concept de colonne d'identité , et utilise la syntaxe SQL standard. Bien que je ne sois pas un expert de MS SQL Server, je pense que ce nouveau support standard est équivalent.

GENERATED … AS IDENTITY

Le GENERATED … AS IDENTITY commande utilisée pendant CREATE TABLE crée une séquence implicite. La création, le nommage, les autorisations et la suppression de cette séquence sont transparents pour vous, contrairement à SERIAL . Très intuitif maintenant. Si vous accordez une autorisation d'utilisation à la table, ils obtiennent l'autorisation pour la séquence. Si vous supprimez la table, la séquence est supprimée automatiquement.

Deux variantes de la syntaxe standard. La différence n'a d'importance que si vous transmettez une valeur plutôt que de laisser une valeur être générée. En règle générale, les gens s'appuient toujours sur la valeur générée, donc normalement vous utiliserez simplement la première version, GENERATED BY DEFAULT AS IDENTITY .

  • GENERATED BY DEFAULT AS IDENTITY
    • Génère une valeur sauf si INSERT la commande fournit une valeur.
  • GENERATED ALWAYS AS IDENTITY
    • Ignore toute valeur fournie par INSERT sauf si vous spécifiez OVERRIDING SYSTEM VALUE

Voir le CREATE TABLE page de documentation.

Lisez cette page intéressante par Peter Eisentraut. Il explique quelques problèmes étranges avec SERIAL . Aucun problème de ce type avec la nouvelle fonctionnalité de colonne d'identité. Il n'y a donc aucune raison d'utiliser SERIAL plus, pas d'inconvénients, seulement des avantages ; SERIAL est remplacé par GENERATED … AS IDENTITY .

Notez qu'une colonne d'identité n'est pas nécessairement une clé primaire et n'est pas automatiquement indexée. Vous devez donc toujours spécifier PRIMARY KEY explicitement si telle est votre intention (comme c'est généralement le cas).

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'intention est que les détails d'implémentation internes vous soient cachés. Vous n'avez pas besoin de connaître le nom de la séquence générée sous les couvertures. Par exemple, vous pouvez réinitialiser le compteur via la colonne sans connaître la séquence sous-jacente.

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

Spécification implicite de l'identité :

  • Colonne des marques NOT NULL
  • Crée une séquence
    • Le type de séquence correspond à la colonne (32 bits 64 bits, etc.)
  • Lie la séquence à la colonne
    • Hérite des autorisations
    • Cascades tombantes
    • Reste lié à la colonne même si la colonne est renommée
  • Spécifie la séquence comme source des valeurs par défaut pour cette colonne

La colonne d'identité peut prendre les mêmes options que CREATE SEQUENCE :

  • START WITH start
  • MINVALUE minvalue | NO MINVALUE
  • MAXVALUE maxvalue | NO MAXVALUE
  • INCREMENT [ BY ] increment
  • CYCLE | NO CYCLE
  • CACHE cache
  • OWNED BY NONE
    ( spécifier la propriété pour la colonne d'identité n'a aucun sens pour moi car la propriété est gérée automatiquement)

Exemple idiot d'options :

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

Ajout de 4 lignes :