ข้อผิดพลาด 1022 - ไม่สามารถเขียนได้ คีย์ซ้ำในตาราง


218

ฉันได้รับข้อผิดพลาด 1,022 ข้อเกี่ยวกับคีย์ที่ซ้ำกันในคำสั่งสร้างตาราง เมื่อดูที่การสืบค้นฉันไม่สามารถเข้าใจได้ว่ามีการทำซ้ำเกิดขึ้นที่ไหน มีใครเห็นไหม

SQL query:

-- -----------------------------------------------------
-- Table `apptwo`.`usercircle`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS  `apptwo`.`usercircle` (

 `idUserCircle` MEDIUMINT NOT NULL ,
 `userId` MEDIUMINT NULL ,
 `circleId` MEDIUMINT NULL ,
 `authUser` BINARY NULL ,
 `authOwner` BINARY NULL ,
 `startDate` DATETIME NULL ,
 `endDate` DATETIME NULL ,
PRIMARY KEY (  `idUserCircle` ) ,
INDEX  `iduser_idx` (  `userId` ASC ) ,
INDEX  `idcategory_idx` (  `circleId` ASC ) ,
CONSTRAINT  `iduser` FOREIGN KEY (  `userId` ) REFERENCES  `apptwo`.`user` (
`idUser`
) ON DELETE NO ACTION ON UPDATE NO ACTION ,
CONSTRAINT  `idcategory` FOREIGN KEY (  `circleId` ) REFERENCES  `apptwo`.`circle` (
`idCircle`
) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE = INNODB;

MySQL said: Documentation

#1022 - Can't write; duplicate key in table 'usercircle' 

4
หากฉันจำได้อย่างถูกต้องคีย์หลักจะเป็น UNIQUE INDEX เสมอดังนั้นคุณจะต้องวางคำสั่งดัชนีที่ไม่ซ้ำกันหรือไม่
Mr47

1
ON DELETE NO ACTIONจะทิ้งการใช้คีย์ต่างประเทศทั้งหมด เว้นแต่คุณจะมีเหตุผลที่เฉพาะเจาะจงในการทำเช่นนั้น
AmazingDreams

4
@AmazingDreams ทำไม? มันยังคงบังคับใช้ Referential Integrity มีเพียงคุณเท่านั้นที่จะลบเด็ก ๆ ได้ด้วยตนเอง วิธีนี้ปลอดภัยกว่าการลบแบบเรียงซ้อนซึ่งคุณสามารถลบข้อมูลจำนวนมากโดยไม่ตั้งใจได้ด้วยการลบคำหลักที่ไม่ถูกต้องหนึ่งคำ
GolezTrol

1
stackoverflow.com/a/5810024/1567737เหตุใดจึงใช้นามแฝงเมื่อใช้ 'นามแฝง' ทำให้วัตถุประสงค์ชัดเจนทันที
AmazingDreams

@AmazingDreams ขอบคุณสำหรับเคล็ดลับ ฉันชอบการอภิปรายรอบ ๆ เช่นกัน - ช่วยให้ฉันเรียนรู้เกี่ยวกับข้อดีข้อเสีย
สามารถใช้ Git ได้

คำตอบ:


534

โอกาสที่คุณจะมีข้อ จำกัด กับชื่อiduserหรือidcategoryในฐานข้อมูลของคุณอยู่แล้ว เพียงเปลี่ยนชื่อข้อ จำกัด หากเป็นเช่นนั้น

ข้อ จำกัด จะต้องไม่ซ้ำกันสำหรับฐานข้อมูลทั้งหมดไม่ใช่เฉพาะตารางที่คุณกำลังสร้าง / แก้ไข

หากต้องการค้นหาว่าข้อ จำกัด ใดที่ใช้งานอยู่ในขณะนี้คุณสามารถใช้แบบสอบถามต่อไปนี้:

SELECT `TABLE_SCHEMA`, `TABLE_NAME`
FROM `information_schema`.`KEY_COLUMN_USAGE`
WHERE `CONSTRAINT_NAME` IN ('iduser', 'idcategory');

15
ตรงตามที่คุณพูด ข้อ จำกัด มากมายถูกสร้างขึ้นโดยอัตโนมัติด้วยชื่อ iduser ประเภทเดียวกันในส่วนที่เหลือของแบบสอบถาม CREATE - ขอบคุณสำหรับความช่วยเหลือของคุณ!
สามารถใช้ Git ได้

1
ฉันคิดว่า MySQL Workbench จะแก้ไขสิ่งนี้เมื่อส่งออกสคริปต์การสร้าง แต่นั่นคือสิ่งที่ฉันได้รับสำหรับ "เพิกเฉย" คำเตือนเกี่ยวกับสิ่งนี้เมื่อฉันเปิดโครงการ
SnowInferno

ขอบคุณเพื่อน :) ที่ช่วยฉันมากและตอนนี้การประชุมของฉันสำหรับคีย์ต่างประเทศแตกต่างกันและฉันไม่สามารถพบปัญหานี้อีกครั้ง :)

สามารถยืนยันได้ว่า แต่ฉันจะทำอย่างไรถ้ามีข้อ จำกัด ที่ตั้งชื่อไว้แม้ว่าตารางอ้างอิงจะถูกลบไปแล้ว? ฉันสามารถลดข้อ จำกัด จากตารางที่ไม่มีอยู่ได้หรือไม่? ฉันเดาว่าควรอัพเดทจาก MySQL 5.6 เป็น MariaDB ปัจจุบัน
Anse

4
ขอบคุณสำหรับสิ่งนี้: ข้อ จำกัด จะต้องไม่ซ้ำกันสำหรับฐานข้อมูลทั้งหมด
sebasira

31

เปลี่ยนชื่อ Foreign Key ใน MySQL คุณไม่สามารถมีชื่อต่างประเทศที่เหมือนกันในตารางฐานข้อมูล

ตรวจสอบตารางทั้งหมดและคีย์ต่างประเทศทั้งหมดของคุณและหลีกเลี่ยงการมีสองคีย์ต่างประเทศด้วยชื่อที่แน่นอนเดียวกัน


นั่นคือปัญหาในกรณีของฉัน ฉันจะไม่เคยเดามันและคุณช่วยวันของฉัน ใช้ fk_id_1, fk_id_2 ฯลฯ ตอนนี้ ขอบคุณ
JackLeEmmerdeur

15

จากลิงก์ทั้งสองที่ได้รับการแก้ไขสำเร็จและอนุสัญญาการตั้งชื่อฉันสามารถแก้ไขปัญหาเดียวกันนี้ได้อย่างง่ายดาย คือสำหรับชื่อคีย์ต่างประเทศให้เป็นfk _colName_ TableName แบบแผนการตั้งชื่อนี้ไม่คลุมเครือและทำให้ ForeignKey ทุกตัวใน DB Model ของคุณไม่เหมือนใครและคุณจะไม่ได้รับข้อผิดพลาดนี้

ข้อผิดพลาด 1,022: ไม่สามารถเขียน; คีย์ซ้ำในตาราง


6

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

ข้อตกลงที่ดีสำหรับการตั้งชื่อข้อ จำกัด กุญแจต่างประเทศคือ:

fk_TableName_ColumnName

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

SELECT * FROM information_schema.table_constraints WHERE constraint_schema = 'YOUR_DB';

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


4

ฉันเพิ่งใช้เวลา 4 ชั่วโมงล่าสุดกับปัญหาเดียวกัน สิ่งที่ฉันทำก็เพื่อให้แน่ใจว่าข้อ จำกัด นั้นมีชื่อเฉพาะ

คุณสามารถเปลี่ยนชื่อข้อ จำกัด ได้ ฉันต่อท้ายหมายเลขของฉันเพื่อให้ฉันสามารถติดตามจำนวนครั้งที่เกิดขึ้นได้อย่างง่ายดาย

ตัวอย่าง

หากข้อ จำกัด ในตารางชื่อ boy พร้อมกับ foreign key X ข้อ จำกัด ถัดไปกับ foreign key X สามารถเรียก boy1

ฉันแน่ใจว่าคุณจะเข้าใจชื่อที่ดีกว่าที่เป็นอยู่ 🙂


3

สิ่งนี้สามารถเกิดขึ้นได้จากการเชื่อมต่อกับบั๊กในเครื่องมือออนไลน์ -con schema-change ของ Percona Toolkit ในการกลายพันธุ์ตารางขนาดใหญ่ pt-osc จะสร้างตารางที่ซ้ำกันก่อนและคัดลอกระเบียนทั้งหมดลงในมัน ภายใต้บางสถานการณ์ pt-osc 2.2.x บางเวอร์ชันจะพยายามให้ข้อ จำกัด ในตารางใหม่ชื่อเดียวกันกับข้อ จำกัด ในตารางเก่า

การแก้ไขได้รับการปล่อยตัวใน 2.3.0

ดูhttps://bugs.launchpad.net/percona-toolkit/+bug/1498128สำหรับรายละเอียดเพิ่มเติม


1

ฉันยังพบปัญหานั้นตรวจสอบว่าชื่อฐานข้อมูลมีอยู่แล้วใน Mysql และเปลี่ยนชื่อเก่า


1

ฉันมีปัญหานี้เมื่อสร้างตารางใหม่ ปรากฎชื่อรหัสต่างประเทศที่ฉันให้ไว้มีการใช้งานแล้ว การเปลี่ยนชื่อรหัสได้รับการแก้ไข

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.