การแก้ไขโครงสร้างตารางเพื่อหลีกเลี่ยง `ข้อผิดพลาด: ค่าคีย์ที่ซ้ำกันละเมิดข้อ จำกัด ที่ไม่ซ้ำกัน '


15

ฉันมีตารางที่สร้างขึ้นด้วยวิธีนี้:

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

ต่อมาบางแถวจะถูกแทรกโดยระบุรหัส:

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

ที่จุดภายหลังบางระเบียนจะถูกแทรกโดยไม่ต้อง ID Error: duplicate key value violates unique constraintและพวกเขาล้มเหลวกับข้อผิดพลาด:

เห็นได้ชัดว่า id ได้รับการกำหนดเป็นลำดับ:

ป้อนคำอธิบายรูปภาพที่นี่

การแทรกที่ล้มเหลวแต่ละครั้งจะเพิ่มตัวชี้ในลำดับจนกระทั่งมันเพิ่มขึ้นเป็นค่าที่ไม่มีอยู่อีกต่อไปและการสืบค้นสำเร็จ

SELECT nextval('jos_content_id_seq'::regclass)

เกิดอะไรขึ้นกับคำจำกัดความของตาราง? วิธีที่ชาญฉลาดในการแก้ไขปัญหานี้คืออะไร


ใน PostgreSQL คุณไม่จำเป็นต้องอ้างชื่อคอลัมน์และชื่อตารางหากมันเป็นตัวพิมพ์เล็กทั้งหมด
Rodrigo

คำตอบ:


19

ไม่มีอะไรผิดปกติกับนิยามตารางของคุณ
(ยกเว้นหมวกผมจะใช้jos_content_idหรือสิ่งแทนชื่อคอลัมน์ที่ไม่ใช่เชิงพรรณนาid.
และผมก็อาจจะใช้textvarchar(50)แทน

INSERTคำชี้แจงของคุณเป็นปัญหา

กับidคอลัมน์กำหนดเป็นคุณไม่ควรใส่ค่าคู่มือserial idสิ่งเหล่านั้นอาจชนกับค่าถัดไปจากลำดับที่เกี่ยวข้อง

จัดทำรายการคอลัมน์เป้าหมายอย่างชัดเจน (ซึ่งเป็นแนวคิดที่ดีสำหรับINSERTงบที่มีอยู่) และละเว้นคอลัมน์อนุกรมทั้งหมด

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

หากคุณต้องการค่าของคอลัมน์ที่สร้างขึ้นโดยอัตโนมัติทันทีให้ใช้RETURNINGข้อ :

INSERT ...
RETURNING id;  -- possibly more

รายละเอียดเพิ่มเติมในคำตอบที่เกี่ยวข้องกับ SO:

หากคุณมีรายการคู่มือในserialคอลัมน์ที่อาจขัดแย้งกันในภายหลังให้ตั้งค่าลำดับสูงสุดของคุณในปัจจุบันidเพื่อแก้ไขปัญหานี้เพียงครั้งเดียว :

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

โดยที่jos_content_id_seqเป็นชื่อเริ่มต้นสำหรับลำดับที่เป็นเจ้าของjos_content.idซึ่งคุณพบในคอลัมน์เริ่มต้นแล้ว ดูเหมือนว่าจะอยู่xhzt8_content_id_seqในกรณีของคุณ


อัปเดต:ปัญหาที่คล้ายกันเกิดขึ้นกับ SO และฉันก็มาพร้อมกับโซลูชันใหม่:


ข้อความช้ากว่า varchar (50) หรือไม่
Rodrigo

2
@Rodrigo: ไม่ได้อยู่ใน Postgres มีการเชื่อมโยงดังกล่าวข้างต้นจะเป็นคำอธิบายเพิ่มเติม: dba.stackexchange.com/a/21496/3684 หรือที่นี่ dba.stackexchange.com/a/89433/3684
Erwin Brandstetter

การทดสอบครั้งสุดท้ายที่นี่ < depesz.com/2010/03/02/charx-vs-varcharx-vs-varchar-vs-text > ทำให้ฉันเชื่อว่า varchar (n) นั้นเร็วกว่าสำหรับเขตส่วนใหญ่ที่การ จำกัด ขนาดมีความสะดวก (คน ชื่ออีเมลที่อยู่ชื่อสปีชีส์ ฯลฯ ) ข้อความเร็วขึ้น (หรือเท่ากัน) หากคุณไม่ตรวจสอบความยาวดูเหมือนว่า
Rodrigo
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.