Score:0

จะลบข้อ จำกัด foreign key ที่ถูกละเลยใน MySQL ได้อย่างไร

ธง in

ใช้ MySQL 5.5 ฉันมีตารางที่ไม่สามารถเพิ่มคีย์ต่างประเทศได้:

แก้ไขตาราง `SOURCE_TABLE` 
    เพิ่มข้อ จำกัด `ข้อ จำกัด FK '
        คีย์ต่างประเทศ (`otherTableID`)
        การอ้างอิง `OTHER_TABLE` (`id`)
        บน ลบ SET NULL
        บน UPDATE CASCADE;

MySQL ส่งคืนข้อผิดพลาดต่อไปนี้:

รหัสข้อผิดพลาด: 1005 ไม่สามารถสร้างตาราง 'my_schema.#sql-4c0c_b6fc8ca' (ข้อผิดพลาด: 121)

มองไปที่ แสดงสถานะ INNODB ของเครื่องยนต์ ฉันเข้าใจ:

------------------------
ข้อผิดพลาดคีย์ต่างประเทศล่าสุด
------------------------
220523 16:34:36 เกิดข้อผิดพลาดในการสร้างข้อจำกัดของคีย์นอกสำหรับตาราง `my_schema`.`#sql-4c0c_b6fc8ca`
ข้อจำกัดคีย์ต่างประเทศของชื่อ `my_schema`.`ConstraintFK`
มีอยู่แล้ว. (โปรดทราบว่าภายใน InnoDB เพิ่ม 'ชื่อฐานข้อมูล'
ข้างหน้าชื่อข้อจำกัดที่ผู้ใช้กำหนด)
โปรดทราบว่าตารางระบบ FOREIGN KEY ของ InnoDB เก็บ
จำกัด ชื่อเป็นแบบคำนึงถึงตัวพิมพ์เล็กและใหญ่ด้วย
การเปรียบเทียบ mySQL มาตรฐาน latin1_swedish_ci ถ้าคุณ
สร้างตารางหรือฐานข้อมูลที่มีชื่อต่างกันเท่านั้น
ตัวพิมพ์เล็กและใหญ่ แล้วชนกันในข้อจำกัด
ชื่อสามารถเกิดขึ้นได้ วิธีแก้ปัญหา: ตั้งชื่อข้อจำกัดของคุณ
อย่างชัดเจนด้วยชื่อเฉพาะ

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

-- แสดงเฉพาะข้อมูลที่เกี่ยวข้องเท่านั้น
สร้างตาราง `SOURCE_TABLE` (
  `id` int(11) ไม่เป็นโมฆะ AUTO_INCREMENT
  `otherTableID` int(11) เริ่มต้นเป็นโมฆะ
  คีย์หลัก (`id`),
  คีย์ `ConstraintFK_idx` (`otherTableID`)
) ENGINE=InnoDB AUTO_INCREMENT=4089 CHARSET เริ่มต้น=utf8;

สร้างตาราง `OTHER_TABLE` (
  `id` int(11) ไม่เป็นโมฆะ AUTO_INCREMENT
  คีย์หลัก (`id`),
) ENGINE=InnoDB AUTO_INCREMENT=58108 CHARSET เริ่มต้น=utf8;

อันที่จริง ถ้าฉันพยายามที่จะละทิ้งข้อจำกัดนั้น:

แก้ไขตาราง `SOURCE_TABLE`
   วางคีย์ต่างประเทศ `ConstraintFK`;

ฉันเข้าใจ:

รหัสข้อผิดพลาด: 1025เกิดข้อผิดพลาดในการเปลี่ยนชื่อ './my_schema/SOURCE_TABLE' เป็น './my_schema/#sql2-4c0c-b6fc8ca' (ข้อผิดพลาด: 152)

ฉันดูที่ระบบไฟล์และไม่เห็นเหตุผลที่การเปลี่ยนชื่อตารางจะล้มเหลว

ขออภัย การพยายามค้นหาสคีมาข้อมูลไม่ได้ผล:

เลือก * จาก information_schema.TABLE_CONSTRAINTS 
    โดยที่ information_schema.TABLE_CONSTRAINTS.CONSTRAINT_TYPE = 'FOREIGN KEY' 
    AND information_schema.TABLE_CONSTRAINTS.CONSTRAINT_NAME = 'ConstraintFK';

ส่งกลับชุดว่างในขณะที่:

เลือก * จาก information_schema.TABLE_CONSTRAINTS 
    โดยที่ information_schema.TABLE_CONSTRAINTS.CONSTRAINT_TYPE = 'FOREIGN KEY' 
    และ information_schema.TABLE_CONSTRAINTS.CONSTRAINT_SCHEMA = 'my_schema';

ส่งคืนข้อ จำกัด ของคีย์นอกทั้งหมดใน my_schema ที่ฉันสามารถรับได้ แสดงการสร้างตาราง คำสั่ง แต่ไม่มีสัญญาณของ ConstraintFK...

มองไปที่ นี้ และ นี้ฉันสงสัยว่ามีบางอย่างเกิดขึ้นในอดีตที่ทำให้คีย์นอกนั้นถูกละเลย: จริงๆ แล้ว SOURCE_TABLE นี้ถูกเปลี่ยนชื่อเมื่อนานมาแล้ว และฉันค่อนข้างมั่นใจว่าคีย์ต่างประเทศที่ฉันพยายามเพิ่มนั้นเคยอยู่ที่นั่นมาก่อน วิธีแก้ปัญหาที่แนะนำคือทิ้งสคีมาและสร้างใหม่จากไฟล์ดัมพ์ มีอะไรอีกบ้างที่ฉันสามารถลองได้โดยไม่ต้องทิ้งสคีมานี้ มันค่อนข้างใหญ่และการหยุดทำงานจะมีความเกี่ยวข้อง

djdomi avatar
za flag
Mauro ฉันขอโทษสำหรับคุณ แต่ dba เป็นไซต์สำหรับคำถามเกี่ยวกับ Db ตั้งค่าสถานะคำถามของคุณสำหรับการเคลื่อนไหวผ่านเหตุผลของชุมชน และเลือกเป็นของไซต์อื่น จากนั้นคุณเลือก dba และคำถามของคุณจะถูกย้ายหลังจากนั้นไม่นาน
ua flag
โปรดระบุ `SHOW CREATE TABLE SOURCE_TABLE;` และ `SHOW CREATE TABLE other_table;'
Mauro Molinari avatar
in flag
@djdomi ฉันค่อนข้างสับสนจริงๆ ฉันพบคำถามมากมายเกี่ยวกับ MySQL ที่นี่เกี่ยวกับข้อผิดพลาดของเซิร์ฟเวอร์และแม้แต่ใน stackoverflow เหตุใดคำถามของฉันจึงควรไปที่ dba แทน
Mauro Molinari avatar
in flag
@RickJames ฉันเพิ่งเพิ่มผลลัพธ์ที่เกี่ยวข้องสำหรับคำสั่ง SHOW CREATE TABLE หากคุณสงสัยเกี่ยวกับประเภทคอลัมน์ แสดงว่าตรงกัน
ua flag
`เลือก constraint_name จาก information_schema.referential_constraits โดยที่ constraint_schema = "my_schema";`
Score:0
ธง in

ในท้ายที่สุด ฉันถูกบังคับให้ทิ้งสคีมาทั้งหมดและกู้คืนด้วยชื่ออื่น จากนั้นทิ้งสคีมาที่มีชื่อเก่า (และประกอบด้วยตัวปัญหา/เสียหาย SOURCE_TABLE).

แท้จริงฉันพบว่า คำตอบนี้ จาก dba.stackexchange.com ซึ่งอธิบายวิธีที่อาจแก้ปัญหานี้ได้และดูเหมือนว่าจะใช้งานได้จริง ... จนถึงจุดหนึ่ง:

  • สร้างตารางใหม่ SOURCE_TABLE ด้วยโครงสร้าง EXACT SAME แต่ชื่อที่มีมาก่อนการเปลี่ยนชื่อ ตรวจสอบให้แน่ใจว่าได้ระบุคีย์นอก (มิฉะนั้น MySQL จะส่งคืนข้อผิดพลาด 150) แต่ใช้ชื่ออื่น (มิฉะนั้น MySQL จะส่งคืนข้อผิดพลาด 121) ตรวจสอบให้แน่ใจว่าชื่อดัชนีสะท้อนถึงชื่อใหม่ของข้อจำกัดของคีย์นอกดังนั้น ในตัวอย่างของฉัน ตารางที่สร้างขึ้นใหม่โดยใช้ชื่อเก่าจะต้องมีคีย์นอกเดียวกัน (ตามที่อธิบายไว้ข้างต้น) แต่มีชื่ออื่น (เช่น ConstrFK แทน ข้อจำกัดFK); ต้องตั้งชื่อดัชนีด้วย ConstrFK_idx (มิฉะนั้นคุณจะได้รับข้อผิดพลาด 121 อีกครั้ง)
  • หากเป็นไปตามทั้งหมดข้างต้น MySQL ควรอนุญาตให้คุณสร้างตารางด้วยชื่อเก่า
  • จากนั้นคุณสามารถวางตารางที่เพิ่งสร้างขึ้นได้
  • จากนั้นกลับไปที่ SOURCE_TABLE และลองสร้างใหม่อีกครั้ง ข้อจำกัดFK ตามที่ต้องการ...ตอนนี้น่าจะใช้ได้แล้ว

อย่างไรก็ตาม ในกรณีของฉัน ด้วย MySQL 5.5.62 (Percona Server) DBMS ล้มเหลวโดยสิ้นเชิงในขั้นตอนสุดท้าย หลังจากที่ฉันเห็นว่าการสร้าง foreign key นั้นประสบความสำเร็จอย่างแท้จริง เมื่อรีสตาร์ท (หลังจากการกู้คืนข้อขัดข้องเสร็จสิ้น) ตารางอยู่ในสถานะที่ไม่สอดคล้องกัน (ทำให้ MySQL Workbench ขัดข้อง ในขณะที่แอปพลิเคชันของฉันดูเหมือนจะบ่นว่า SOURCE_TABLE ไม่มีอยู่อีกต่อไป) ดังนั้น เพื่อออกจากสถานการณ์เลวร้ายนั้น ฉันจำใจต้องทิ้งสคีมาทั้งหมด (ฉันทำงานในแบบจำลองที่ทันสมัย ​​ซึ่งมี SOURCE_TABLE ยังคงเหมือนเดิม) นำเข้าใหม่เป็น schema ใหม่ จากนั้นวาง schema กับตารางที่มีปัญหาและกำจัดอาการปวดหัวนี้ทั้งหมด... แน่นอนว่าต้องใช้เวลาหยุดทำงานอย่างน้อยสองสามชั่วโมง...

djdomi avatar
za flag
นั่นเป็นเหตุผลที่ฉันพูดว่า dba จะเป็นทางออกของคุณ ;)

โพสต์คำตอบ

คนส่วนใหญ่ไม่เข้าใจว่าการถามคำถามมากมายจะปลดล็อกการเรียนรู้และปรับปรุงความสัมพันธ์ระหว่างบุคคล ตัวอย่างเช่น ในการศึกษาของ Alison แม้ว่าผู้คนจะจำได้อย่างแม่นยำว่ามีคำถามกี่ข้อที่ถูกถามในการสนทนา แต่พวกเขาไม่เข้าใจความเชื่อมโยงระหว่างคำถามและความชอบ จากการศึกษาทั้ง 4 เรื่องที่ผู้เข้าร่วมมีส่วนร่วมในการสนทนาด้วยตนเองหรืออ่านบันทึกการสนทนาของผู้อื่น ผู้คนมักไม่ตระหนักว่าการถามคำถามจะมีอิทธิพลหรือมีอิทธิพลต่อระดับมิตรภาพระหว่างผู้สนทนา