Ich habe eine Tabelle, die folgendermaßen erstellt wird:
--
-- Table: #__content
--
CREATE TABLE "jos_content" (
"id" serial NOT NULL,
"asset_id" bigint DEFAULT 0 NOT NULL,
...
"xreference" varchar(50) DEFAULT '' NOT NULL,
PRIMARY KEY ("id")
);
Später werden unter Angabe der ID einige Zeilen eingefügt:
INSERT INTO "jos_content" VALUES (1,36,'About',...)
Zu einem späteren Zeitpunkt werden einige Datensätze ohne id eingefügt und sie nicht mit dem Fehler:
Error: duplicate key value violates unique constraint
.
Anscheinend wurde die ID als Sequenz definiert:
Jede fehlgeschlagene Einfügung erhöht den Zeiger in der Sequenz, bis er auf einen Wert erhöht wird, der nicht mehr vorhanden ist und die Abfragen erfolgreich sind.
SELECT nextval('jos_content_id_seq'::regclass)
Was ist falsch an der Tabellendefinition? Was ist der clevere Weg, dies zu beheben?
postgresql
database-design
insert
auto-increment
sequence
Valentin Despa
quelle
quelle
Antworten:
An Ihrer Tabellendefinition ist nichts falsch.
(Außer Hut würde ich verwenden
jos_content_id
oder etwas anstelle der nicht-deskriptiven Spaltennamenid
.Und ich würde wahrscheinlich verwenden
text
stattvarchar(50)
.Ihre
INSERT
Aussage ist das Problem.Wenn Ihre
id
Spalte als definiert istserial
, sollten Sie keine manuellen Werte für einfügenid
. Diese können mit dem nächsten Wert aus der zugehörigen Sequenz kollidieren.Stellen Sie eine explizite Liste der Zielspalten bereit (was fast immer eine gute Idee für dauerhafte
INSERT
Anweisungen ist) und lassen Sie serielle Spalten vollständig weg .Wenn Sie die Werte von automatisch generierten Spalten sofort benötigen, verwenden Sie die folgende
RETURNING
Klausel :Weitere Details in dieser verwandten Antwort zu SO:
Wenn Sie manuelle Einträge in
serial
Spalten haben, die später zu Konflikten führen können, setzen Sie Ihre Sequenz auf das aktuelle Maximumid
, um dies einmal zu beheben :Wo
jos_content_id_seq
ist der Standardname für eine Sequenz, deren Eigentümerjos_content.id
Sie bereits in der Standardspalte gefunden haben? Scheintxhzt8_content_id_seq
in deinem Fall zu sein;Update: Ein ähnliches Problem tauchte bei SO auf und ich fand eine neue Lösung:
quelle