`Hata: yinelenen anahtar değeri benzersiz kısıtlamayı ihlal ediyor` önlemek için tablo yapısını düzeltme


15

Bu şekilde oluşturulan bir tablo var:

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

Daha sonra kimliği belirten bazı satırlar eklenir:

INSERT INTO "jos_content" VALUES (1,36,'About',...)

Daha sonraki bir noktada bazı kayıtlar id olmadan yerleştirilir ve bunlar hata ile başarısız: Error: duplicate key value violates unique constraint.

Görünüşe göre kimlik bir dizi olarak tanımlandı:

resim açıklamasını buraya girin

Başarısız olan her ekleme, artık var olmayan bir değere yükselene ve sorgular başarılı oluncaya kadar sıradaki işaretçiyi artırır.

SELECT nextval('jos_content_id_seq'::regclass)

Tablo tanımında sorun nedir? Bunu düzeltmenin akıllı yolu nedir?


PostgreSQL'de sütun ve tablo adlarını küçük harfle belirtmeniz gerekmez.
Rodrigo

Yanıtlar:


19

Tablo tanımınızda yanlış bir şey yok.
(Kullanacağım şapka jos_content_idveya açıklayıcı olmayan sütun adı yerine bir şey hariç id.
Ve muhtemelen yerine kullanacağımtextvarchar(50) .

İfadeniz INSERTsorun.

Senin ile idkolon olarak tanımlanan serial, sizin için manuel değerleri eklemek gerekir id. Bunlar ilişkili dizideki bir sonraki değerle çarpışabilir.

Hedef sütunların açık bir listesini (kalıcı INSERTifadeler için neredeyse her zaman iyi bir fikirdir ) sağlayın ve seri sütunları tamamen atlayın .

INSERT INTO jos_content(asset_id, some_column, ...)
VALUES (36,'About',...);

Otomatik olarak oluşturulan sütun (lar) ın değerlerine hemen ihtiyacınız varsa, aşağıdaki RETURNINGmaddeyi kullanın :

INSERT ...
RETURNING id;  -- possibly more

SO ile ilgili bu cevapta daha fazla ayrıntı:

Daha serialsonra çakışabilecek sütunlarda manuel girişleriniz varsa , bunu bir kez düzeltmekid için sıranızı geçerli maksimum değere ayarlayın :

SELECT setval('jos_content_id_seq', max(id))
FROM   jos_content;

Sahip jos_content_id_seqolunan bir dizinin varsayılan adı, varsayılan jos_content.idolarak sütun varsayılanında zaten bulunur. xhzt8_content_id_seqSizin durumunuzda gibi görünüyor ;


Güncelleme: Benzer bir sorun SO'da ortaya çıktı ve yeni bir çözüm buldum:


Metin varchar (50) 'den daha yavaş değil mi?
Rodrigo

2
@ Rodrigo: Postgres'te değil. Yukarıda daha fazla açıklama için bir bağlantı vardır: dba.stackexchange.com/a/21496/3684 . Veya burada. dba.stackexchange.com/a/89433/3684
Erwin Brandstetter

Buradaki son test < depesz.com/2010/03/02/charx-vs-varcharx-vs-varchar-vs-text > beni, boyut kısıtlamasının uygun olduğu çoğu alan için varchar (n) 'nın daha hızlı olduğuna ikna etti (insanlar isimler, e-postalar, adresler, tür isimleri, vb.). Uzunluğunu kontrol etmezseniz metin daha hızlıdır (veya aynıdır).
Rodrigo
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.