Comment définir la clé primaire d'incrémentation automatique dans PostgreSQL?

259

J'ai une table dans PostgreSQL avec 22 colonnes, et je veux ajouter une clé primaire d'incrémentation automatique.

J'ai essayé de créer une colonne appelée idde type BIGSERIAL mais pgadmin a répondu avec une erreur:

ERROR: sequence must have same owner as table it is linked to.

Quelqu'un sait-il comment résoudre ce problème? Comment ajouter une clé primaire à incrémentation automatique dans PostgreSQL sans recréer la table?

mkn
la source

Réponses:

292

Essayez cette commande:

ALTER TABLE your_table ADD COLUMN key_column BIGSERIAL PRIMARY KEY;

Essayez-le avec le même utilisateur de base de données que celui que vous avez créé la table.

AH
la source
75
(la clé ici est d'utiliser un type de données SERIAL ou BIGSERIAL, qui crée une séquence dans les coulisses et l'incrémente / l'utilise au moment de l'insertion)
rogerdpack
16
et si vous voulez le référencer à partir d'une autre table, utilisez entier ou bigint
Ward
2
@satishkilari: oui, la syntaxe est ALTER TABLE mytable ADD PRIMARY KEY (column);. Postgresql vérifiera que la colonne ne contient aucun NULL.
AH
3
Obtenir cette erreur dans pgAdmin 4. Les deux bigserialet serialdonnent la même erreur:ERROR: syntax error at or near "BIGSERIAL"
adi
5
Obtention également de l'erreur de syntaxe en utilisant bigserial ou serial. Existe-t-il une version postgresql minimale pour cela?
dacDave
251

Incrémentation automatique de la clé primaire dans postgresql:

Étape 1, créez votre table:

CREATE TABLE epictable
(
    mytable_key    serial primary key,
    moobars        VARCHAR(40) not null,
    foobars        DATE
);

Étape 2, insérez des valeurs dans votre table comme ceci, notez que mytable_key n'est pas spécifié dans la première liste de paramètres, cela entraîne l'auto-incrémentation de la séquence par défaut.

insert into epictable(moobars,foobars) values('delicious moobars','2012-05-01')
insert into epictable(moobars,foobars) values('worldwide interblag','2012-05-02')

Étape 3, sélectionnez * dans votre tableau:

el@voyager$ psql -U pgadmin -d kurz_prod -c "select * from epictable"

Étape 4, interprétez la sortie:

mytable_key  |        moobars        |  foobars   
-------------+-----------------------+------------
           1 | delicious moobars     | 2012-05-01
           2 | world wide interblags | 2012-05-02
(2 rows)

Observez que la colonne mytable_key a été incrémentée automatiquement.

ProTip:

Vous devez toujours utiliser une clé primaire sur votre table car postgresql utilise en interne des structures de table de hachage pour augmenter la vitesse des insertions, suppressions, mises à jour et sélections. Si une colonne de clé primaire (qui est forcée unique et non nulle) est disponible, elle peut être utilisée pour fournir une valeur de départ unique pour la fonction de hachage. Si aucune colonne de clé primaire n'est disponible, la fonction de hachage devient inefficace car elle sélectionne un autre ensemble de colonnes comme clé.

Eric Leschinski
la source
21
Un nitpick mineur, SERIALcrée un sequencedans les coulisses: postgresql.org/docs/9.2/static/…
carbocation
1
est-il possible de faire la clé primaire (colonne existante) dans une table sans ajouter de nouvelle colonne
satish kilari
une clé étrangère déclarée au thing_id int references epictable(mytable_key)travail?
36

Créez une clé primaire à incrémentation automatique dans postgresql, à l'aide d'une séquence personnalisée:

Étape 1, créez votre séquence:

create sequence splog_adfarm_seq
    start 1
    increment 1
    NO MAXVALUE
    CACHE 1;
ALTER TABLE fact_stock_data_detail_seq
OWNER TO pgadmin;

Étape 2, créez votre table

CREATE TABLE splog_adfarm
(
    splog_key    INT unique not null,
    splog_value  VARCHAR(100) not null
);

Étape 3, insérez dans votre table

insert into splog_adfarm values (
    nextval('splog_adfarm_seq'), 
    'Is your family tree a directed acyclic graph?'
);

insert into splog_adfarm values (
    nextval('splog_adfarm_seq'), 
    'Will the smart cookies catch the crumb?  Find out now!'
);

Étape 4, observez les rangées

el@defiant ~ $ psql -U pgadmin -d kurz_prod -c "select * from splog_adfarm"

splog_key |                            splog_value                             
----------+--------------------------------------------------------------------
        1 | Is your family tree a directed acyclic graph?
        2 | Will the smart cookies catch the crumb?  Find out now!
(3 rows)

Les deux lignes ont des clés qui commencent à 1 et sont incrémentées de 1, comme défini par la séquence.

Bonus Elite ProTip:

Les programmeurs détestent taper et taper nextval('splog_adfarm_seq')est ennuyeux. Vous pouvez DEFAULTplutôt taper ce paramètre, comme ceci:

insert into splog_adfarm values (
    DEFAULT, 
    'Sufficient intelligence to outwit a thimble.'
);

Pour que ce qui précède fonctionne, vous devez définir une valeur par défaut pour cette colonne clé sur la table splog_adfarm. Ce qui est plus joli.

Eric Leschinski
la source
2
Quels sont les avantages des séquences personnalisées? Probablement, la sécurité?
Léo Léopold Hertz 준영
1
@Masi Une utilisation d'une séquence personnalisée pourrait être de faciliter la réplication maître-maître - ce qui serait utile si la liaison de données entre deux centres de données est rompue - permettant de créer des enregistrements sur les deux serveurs avec des ID différents, ce qui permet ensuite de synchroniser facilement les bases de données de sauvegarde tout en conservant les identifiants générés dans des emplacements séparés.
Vincent McNabb
16

Si vous voulez le faire dans pgadmin, c'est beaucoup plus facile. Il semble dans postgressql, pour ajouter un incrémentation automatique à une colonne, nous devons d'abord créer une séquence d'incrémentation automatique et l'ajouter à la colonne requise. J'ai aimé ça.

1) Tout d'abord, vous devez vous assurer qu'il existe une clé primaire pour votre table. Conservez également le type de données de la clé primaire en bigint ou smallint. (J'ai utilisé bigint, je n'ai pas pu trouver un type de données appelé série comme mentionné dans d'autres réponses ailleurs)

2) Ajoutez ensuite une séquence en cliquant avec le bouton droit sur séquence-> ajouter une nouvelle séquence . S'il n'y a pas de données dans le tableau, laissez la séquence telle quelle, n'apportez aucune modification. Enregistrez-le. S'il existe des données existantes, ajoutez la dernière valeur ou la valeur la plus élevée dans la colonne de clé primaire à l'onglet Valeur actuelle dans les définitions, comme illustré ci-dessous. entrez la description de l'image ici

3) Enfin, ajoutez la ligne nextval('your_sequence_name'::regclass)à la valeur par défaut dans votre clé primaire comme indiqué ci-dessous.

entrez la description de l'image ici Assurez-vous que le nom de la séquence est correct ici. C'est tout et l'incrémentation automatique devrait fonctionner.

toing_toing
la source
9

Si vous souhaitez utiliser des nombres dans une séquence, définissez une nouvelle séquence avec quelque chose comme

CREATE SEQUENCE public.your_sequence
    INCREMENT 1
    START 1
    MINVALUE 1
;

puis modifiez la table pour utiliser la séquence de l'id:

ALTER TABLE ONLY table ALTER COLUMN id SET DEFAULT nextval('your_sequence'::regclass);
acaruci
la source
Dois-je créer une nouvelle séquence pour chaque table?
Bharat Chhabra
Vous pouvez partager la même séquence pour différentes tables, mais la séquence augmentera pour chaque enregistrement de chaque table.
acaruci
1

J'ai essayé le script suivant pour réussir l'incrémentation automatique de la clé primaire dans PostgreSQL.

CREATE SEQUENCE dummy_id_seq
    START WITH 1
INCREMENT BY 1
NO MINVALUE
NO MAXVALUE
CACHE 1;

CREATE table dummyTable (
    id bigint DEFAULT nextval('dummy_id_seq'::regclass) NOT NULL,
    name character varying(50)
);

ÉDITER:

CREATE table dummyTable (
    id SERIAL NOT NULL,
    name character varying(50)
)

Le mot-clé SERIAL crée automatiquement une séquence pour la colonne respective.

Asad Shakeel
la source
Pouvez-vous réinitialiser un SERIAL comme vous le faites pour une SEQUENCE?
thoroc
1
Ouais !, j'ai vérifié avec ALTER SEQUENCE dummytable_id_seq RESTART WITH 1;et son fonctionnement.
Asad Shakeel
0

Je suis peut-être un peu en retard pour répondre à cette question, mais je travaille sur ce sujet à mon travail :)

Je voulais écrire la colonne 'a_code' = c1, c2, c3, c4 ...

J'ai d'abord ouvert une colonne avec le nom ref_idet le type serial. Ensuite, j'ai résolu mon problème avec cette commande:

update myschema.mytable set a_code=cast('c'||"ref_id" as text) 
user5838061
la source
est-il possible de faire la clé primaire (colonne existante) dans une table sans ajouter de nouvelle colonne
satish kilari