คุณส่งออกฐานข้อมูล แล้วลองโหลดมันเข้าอินสแตนซ์ใหม่ และ MySQL ก็แจ้งข้อผิดพลาด:
หรือบน PostgreSQL:
DETAIL: Key (user_id)=(42) is not present in table "users".
ทำไมจึงเกิดขึ้น
foreign key กำหนดว่า “ทุก orders.user_id ต้องชี้ไปยัง users.id ที่มีอยู่จริง” เมื่อ dump แทรก orders ก่อน users แถวแม่ที่ถูกอ้างอิงยังไม่มีอยู่ ฐานข้อมูลจึงปฏิเสธแถวนั้น
เครื่องมือ dump ส่วนใหญ่เขียนตารางแบบ เรียงตามตัวอักษร หรือ ตามลำดับการสร้าง ไม่ใช่ตามลำดับการพึ่งพา foreign key ดังนั้น orders (ลูก) จึงมักถูกวางไว้ก่อน users (แม่) และการนำเข้าก็พังลง
วิธีที่ 1: จัดลำดับ INSERT ใหม่ตามการพึ่งพา (วิธีที่ถูกต้อง)
ทางออกที่สะอาดคือแทรกทุกตารางแม่ก่อนตารางลูกของมัน ซึ่งหมายถึงการแก้ไข foreign key ให้กลายเป็นกราฟการพึ่งพา แล้วโหลดตารางใน ลำดับเชิงทอพอโลยี (topological order): users → orders → order_items
การทำสิ่งนี้ด้วยมือในไฟล์ขนาดหลายกิกะไบต์นั้นเจ็บปวด คุณต้องไล่ตามทุก FOREIGN KEY ทั้งใน CREATE TABLE และ ALTER TABLE แล้วตัด/วางบล็อก INSERT ขนาดใหญ่ให้อยู่ในลำดับที่ถูกต้อง
วิธีที่ 2: ปิดการตรวจสอบ foreign key ระหว่างนำเข้า
สำหรับ dump ที่สมบูรณ์และสอดคล้องกันอยู่แล้ว คุณสามารถข้ามการตรวจสอบระหว่างโหลดได้อย่างปลอดภัย บน MySQL ให้ครอบไฟล์ด้วย:
-- MySQL SET FOREIGN_KEY_CHECKS = 0; -- ... คำสั่ง INSERT ทั้งหมดของคุณ ... SET FOREIGN_KEY_CHECKS = 1;
บน PostgreSQL ให้เลื่อนการตรวจสอบ constraint ออกไปภายในทรานแซกชัน:
-- PostgreSQL BEGIN; SET CONSTRAINTS ALL DEFERRED; -- ... คำสั่ง INSERT ทั้งหมดของคุณ ... COMMIT;
เปิดการตรวจสอบกลับหลังจากนั้นเพื่อให้การเขียนในอนาคตยังถูกตรวจสอบอยู่ วิธีนี้ใช้ได้ แต่มันเพียงกลบปัญหาเรื่องลำดับไว้เท่านั้น หาก dump เป็นแบบ ไม่สมบูรณ์ คุณก็ยังอาจได้แถวที่ไม่มีแม่ (orphaned rows) อยู่ดี
วิธีที่ 3: ทำทั้งสองอย่างโดยอัตโนมัติด้วย DumpCleaner
DumpCleaner อ่าน dump ดึงทุก foreign key ออกจาก CREATE TABLE และ ALTER TABLE สร้างกราฟการพึ่งพา แล้วส่งออกไฟล์ที่สะอาดซึ่งนำเข้าได้ทันที:
- ลาก
.sqldump ของคุณเข้าไปใน DumpCleaner (MySQL, MariaDB, PostgreSQL, SQLite หรือ MS SQL) - เลือก ลำดับ INSERT → ตามการพึ่งพา (รู้จัก FK) ตารางแม่จะถูกวางไว้ก่อนตารางลูกโดยอัตโนมัติผ่านการเรียงลำดับเชิงทอพอโลยี
- ติ๊ก ปิดการตรวจสอบ foreign key ได้ตามต้องการ มันจะครอบผลลัพธ์ด้วยคำสั่งที่ถูกต้องสำหรับฐานข้อมูลของคุณ
- ส่งออก แล้วนำเข้าไฟล์ใหม่ ข้อผิดพลาด constraint หายไปแล้ว
มันยังตรวจจับ foreign key แบบวนซ้ำ (circular) และเตือนคุณ แทนที่จะสร้างลำดับที่เป็นไปไม่ได้
ไม่ต้องผ่าตัด INSERT ด้วยมืออีกต่อไป
DumpCleaner จัดลำดับ insert ใหม่ตามการพึ่งพา foreign key บนไฟล์ทุกขนาด แบบสตรีมมิ่ง ใช้หน่วยความจำคงที่ แอปเนทีฟสำหรับ macOS & iPadOS ซื้อครั้งเดียวจบ
ดาวน์โหลดบน App Storeคำถามที่พบบ่อย
ทำไม “a foreign key constraint fails” จึงเกิดขึ้นตอนนำเข้า?
แถวลูกอ้างอิงถึงแถวแม่ที่ยังไม่ได้ถูกแทรก เพราะ dump จัดลำดับ INSERT ตามตัวอักษรหรือตามเวลาที่สร้าง แทนที่จะเรียงตามการพึ่งพา foreign key
ปลอดภัยไหมที่จะปิดการตรวจสอบ foreign key ระหว่างนำเข้า?
ปลอดภัย สำหรับ dump ที่สมบูรณ์และสอดคล้องกัน คุณเพียงข้ามการตรวจสอบข้อมูลที่ถูกต้องอยู่แล้วในฐานข้อมูลต้นทาง อย่าลืมเปิดการตรวจสอบกลับหลังจากนั้น
จะจัดลำดับ INSERT ใหม่โดยไม่ต้องแก้ไฟล์ด้วยมือได้อย่างไร?
DumpCleaner ตรวจจับ foreign key สร้างกราฟการพึ่งพา แล้วส่งออก INSERT ในลำดับเชิงทอพอโลยี ตารางแม่จึงถูกโหลดก่อนตารางลูกเสมอ
วิธีนี้ใช้กับ PostgreSQL ได้ด้วยไหม?
ได้ DumpCleaner รองรับผลลัพธ์จาก pg_dump และสามารถสร้าง SET CONSTRAINTS ALL DEFERRED รวมถึง insert ที่เรียงตามการพึ่งพาได้
นำเข้า dump โดยไม่ปวดหัวเรื่อง FK
ลาก จัดลำดับใหม่ตามการพึ่งพา ส่งออก DumpCleaner จัดการ foreign key ให้ การนำเข้าของคุณจึงทำงานได้ราบรื่น
ดาวน์โหลดบน App Store