Wie setze ich den Auto-Inkrement-Primärschlüssel in PostgreSQL?

259

Ich habe eine Tabelle in PostgreSQL mit 22 Spalten und möchte einen Primärschlüssel mit automatischer Inkrementierung hinzufügen.

Ich habe versucht, eine Spalte mit dem Namen idBIGSERIAL zu erstellen, aber pgadmin hat mit einem Fehler geantwortet:

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

Weiß jemand, wie man dieses Problem behebt? Wie füge ich in PostgreSQL einen automatisch inkrementierenden Primärschlüssel hinzu, ohne die Tabelle erneut zu erstellen?

mkn
quelle

Antworten:

292

Versuchen Sie diesen Befehl:

ALTER TABLE your_table ADD COLUMN key_column BIGSERIAL PRIMARY KEY;

Versuchen Sie es mit dem gleichen DB-Benutzer , wie die, die Sie haben , erstellt die Tabelle.

AH
quelle
75
(Der Schlüssel hier ist die Verwendung eines SERIAL- oder BIGSERIAL-Datentyps, der eine Sequenz hinter den Kulissen erstellt und diese beim Einfügen erhöht / verwendet.)
Rogerdpack
16
und wenn Sie es aus einer anderen Tabelle referenzieren möchten, verwenden Sie Integer oder Bigint
Ward
2
@ Satishkilari: Ja, die Syntax ist ALTER TABLE mytable ADD PRIMARY KEY (column);. Postgresql überprüft, ob die Spalte keine NULL-Werte enthält.
AH
3
Erhalten dieses Fehlers in pgAdmin 4. Beide bigserialund serialgeben den gleichen Fehler:ERROR: syntax error at or near "BIGSERIAL"
adi
5
Erhalten Sie auch den Syntaxfehler mit bigserial oder serial. Gibt es dafür eine minimale postgresql-Version?
dacDave
251

Primärschlüssel inkrementieren in postgresql:

Schritt 1, erstellen Sie Ihre Tabelle:

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

Schritt 2: Fügen Sie Werte wie folgt in Ihre Tabelle ein. Beachten Sie, dass mytable_key nicht in der ersten Parameterliste angegeben ist. Dadurch wird die Standardsequenz automatisch inkrementiert.

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

Schritt 3, wählen Sie * aus Ihrer Tabelle:

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

Schritt 4, interpretieren Sie die Ausgabe:

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

Beachten Sie, dass die Spalte mytable_key automatisch inkrementiert wurde.

ProTip:

Sie sollten immer einen Primärschlüssel für Ihre Tabelle verwenden, da postgresql intern Hash-Tabellenstrukturen verwendet, um die Geschwindigkeit beim Einfügen, Löschen, Aktualisieren und Auswählen zu erhöhen. Wenn eine Primärschlüsselspalte (die als eindeutig und nicht null erzwungen wird) verfügbar ist, kann davon abhängig gemacht werden, dass ein eindeutiger Startwert für die Hash-Funktion bereitgestellt wird. Wenn keine Primärschlüsselspalte verfügbar ist, wird die Hash-Funktion ineffizient, da ein anderer Satz von Spalten als Schlüssel ausgewählt wird.

Eric Leschinski
quelle
21
Eine kleinere nitpick, SERIALschafft einen Blick sequencehinter den Kulissen: postgresql.org/docs/9.2/static/...
Carbo
1
ist es möglich, Primärschlüssel (vorhandene Spalte) in einer Tabelle zu
erstellen,
Wird ein Fremdschlüssel mit thing_id int references epictable(mytable_key)Arbeit deklariert ?
36

Erstellen Sie einen automatisch inkrementierenden Primärschlüssel in postgresql in einer benutzerdefinierten Reihenfolge:

Schritt 1, erstellen Sie Ihre Sequenz:

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

Schritt 2, erstellen Sie Ihre Tabelle

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

Schritt 3, in Ihre Tabelle einfügen

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!'
);

Schritt 4, beobachten Sie die Zeilen

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)

Die beiden Zeilen haben Schlüssel, die bei 1 beginnen und gemäß der Reihenfolge um 1 erhöht werden.

Bonus Elite ProTip:

Programmierer hassen das Tippen, und das Tippen nextval('splog_adfarm_seq')ist ärgerlich. Sie können DEFAULTstattdessen für diesen Parameter Folgendes eingeben:

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

Damit dies funktioniert, müssen Sie einen Standardwert für diese Schlüsselspalte in der Tabelle splog_adfarm definieren. Welches ist schöner.

Eric Leschinski
quelle
2
Was sind die Vorteile von benutzerdefinierten Sequenzen? Wahrscheinlich Sicherheit?
Léo Léopold Hertz 3
1
@Masi Eine Verwendung einer benutzerdefinierten Sequenz könnte darin bestehen, die Master-Master-Replikation zu vereinfachen. Dies wäre nützlich, wenn die Datenverbindung zwischen zwei Rechenzentren unterbrochen wird, sodass auf beiden Servern Datensätze mit unterschiedlichen IDs erstellt werden können Dann ist es einfach, die Datenbanken wieder zu synchronisieren, während die generierten IDs an den verschiedenen Speicherorten gespeichert werden.
Vincent McNabb
16

Wenn Sie dies in pgadmin tun möchten, ist es viel einfacher. Um in postgressql ein automatisches Inkrement zu einer Spalte hinzuzufügen, müssen wir zunächst eine automatische Inkrementierungssequenz erstellen und sie der erforderlichen Spalte hinzufügen. Das hat mir gefallen.

1) Zunächst müssen Sie sicherstellen, dass für Ihre Tabelle ein Primärschlüssel vorhanden ist. Behalten Sie außerdem den Datentyp des Primärschlüssels in bigint oder smallint bei. (Ich habe bigint verwendet und konnte keinen Datentyp namens serial finden, wie in anderen Antworten an anderer Stelle erwähnt.)

2) Fügen Sie dann eine Sequenz hinzu, indem Sie mit der rechten Maustaste auf Sequenz-> Neue Sequenz hinzufügen klicken . Wenn die Tabelle keine Daten enthält, lassen Sie die Reihenfolge unverändert und nehmen Sie keine Änderungen vor. Speichern Sie es einfach. Wenn Daten vorhanden sind, fügen Sie den letzten oder höchsten Wert in der Primärschlüsselspalte zum aktuellen Wert auf der Registerkarte Definitionen hinzu, wie unten gezeigt. Geben Sie hier die Bildbeschreibung ein

3) Fügen Sie abschließend die Zeile nextval('your_sequence_name'::regclass)wie unten gezeigt zum Standardwert in Ihrem Primärschlüssel hinzu.

Geben Sie hier die Bildbeschreibung ein Stellen Sie sicher, dass der Sequenzname hier korrekt ist. Dies ist alles und das automatische Inkrementieren sollte funktionieren.

toing_toing
quelle
9

Wenn Sie Zahlen in einer Sequenz verwenden möchten, definieren Sie eine neue Sequenz mit so etwas wie

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

und ändern Sie dann die Tabelle, um die Reihenfolge für die ID zu verwenden:

ALTER TABLE ONLY table ALTER COLUMN id SET DEFAULT nextval('your_sequence'::regclass);
acaruci
quelle
Muss ich für jede Tabelle eine neue Sequenz erstellen?
Bharat Chhabra
Sie können dieselbe Sequenz für verschiedene Tabellen verwenden, die Sequenz wird jedoch für jeden Datensatz in jeder Tabelle erhöht.
Acaruci
1

Ich habe das folgende Skript versucht, um den Primärschlüssel in PostgreSQL erfolgreich automatisch zu erhöhen.

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)
);

BEARBEITEN:

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

Das Schlüsselwort SERIAL erstellt automatisch eine Sequenz für die jeweilige Spalte.

Asad Shakeel
quelle
Können Sie eine SERIE zurücksetzen, wie Sie es für eine SEQUENZ tun?
Thoroc
1
Ja!, Ich habe nachgefragt ALTER SEQUENCE dummytable_id_seq RESTART WITH 1;und es funktioniert.
Asad Shakeel
0

Vielleicht bin ich etwas spät dran, um diese Frage zu beantworten, aber ich arbeite in meinem Job an diesem Thema :)

Ich wollte die Spalte 'a_code' = c1, c2, c3, c4 schreiben ...

Zuerst habe ich eine Spalte mit dem Namen ref_idund dem Typ geöffnet serial. Dann habe ich mein Problem mit diesem Befehl gelöst:

update myschema.mytable set a_code=cast('c'||"ref_id" as text) 
user5838061
quelle
ist es möglich, Primärschlüssel (vorhandene Spalte) in einer Tabelle zu
erstellen,