การแก้ไขปัญหา Multiple Foreign Key ใน MySQL: คู่มือทีละขั้นตอน

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

ปัญหา

ลองนึกภาพว่าคุณมีตาราง SHIPPING_DETAILS ที่รับผิดชอบในการติดตามผู้ให้บริการจัดส่ง (เช่น FedEx หรือ UPS) และผู้ให้บริการในการจัดการผลิตภัณฑ์ (ลองคิดถึง Dunder Mifflin) ในกรณีนี้ หลายคอลัมน์ในรายละเอียดการจัดส่งต้องอิงอ้างถึงตารางหลักเดียวกัน คือ VENDOR อย่างไรก็ตาม อาจมีปัญหาเกิดขึ้นเมื่อคุณพยายามสร้างข้อกำหนดคีย์ต่างประเทศสำหรับคอลัมน์เหล่านี้ เช่น ไม่สามารถกำหนดคีย์ต่างประเทศหลายตัวได้

ผู้ใช้งานมักพบข้อผิดพลาดเช่น:

Can't create table './<DB_NAME>/SHIPPING_GRID.frm' (errno: 150)

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

ภาพรวมของแนวทางแก้ไข

ในการแก้ไขปัญหาการกำหนดคีย์ต่างประเทศหลายตัวใน MySQL ให้ทำตามขั้นตอนต่อไปนี้:

  1. กำหนดโครงสร้างตารางอย่างถูกต้อง: ตรวจสอบให้แน่ใจว่าตาราง VENDOR ของคุณมีคีย์หลักที่ไม่ซ้ำกันซึ่งเข้ากันได้กับคอลัมน์คีย์ต่างประเทศในตาราง SHIPPING_DETAILS ของคุณ

  2. แก้ไขประเภทตาราง: ให้แน่ใจว่าทั้งสองตาราง (VENDOR และ SHIPPING_GRID) มีประเภทเป็น InnoDB ซึ่งเป็นสิ่งสำคัญ เนื่องจากข้อกำหนดคีย์ต่างประเทศไม่สนับสนุนในเครื่องจัดเก็บข้อมูลอื่น เช่น MyISAM

  3. ตรวจสอบความเข้ากันได้ของประเภทข้อมูล: ยืนยันว่าประเภทข้อมูลของคีย์ต่างประเทศตรงกับประเภทข้อมูลของคีย์หลักที่มันอ้างอิง ตัวอย่างเช่น หาก VENDOR.no ถูกกำหนดเป็น INT(6) คีย์ต่างประเทศทั้งหมดต้องเป็นประเภทเดียวกัน

  4. หลีกเลี่ยงการกำหนดคีย์หลักซ้ำกัน: ตรวจสอบให้แน่ใจว่า SQL ของคุณไม่รวมข้อกำหนดคีย์หลักที่ซ้ำกันโดยไม่ตั้งใจ สิ่งนี้อาจนำไปสู่ข้อผิดพลาดขณะสร้างตาราง

ตัวอย่างโค้ด

นี่คือตัวอย่างที่ถูกต้องว่า ตาราง SHIPPING_GRID ของคุณจะถูกกำหนดอย่างถูกต้องอย่างไรหลังจากพิจารณาจุดด้านบน:

CREATE TABLE SHIPPING_GRID(  
    id INT NOT NULL AUTO_INCREMENT PRIMARY KEY COMMENT 'Unique ID for each row',
    shipping_vendor_no INT(6) NOT NULL COMMENT 'Foreign key to VENDOR.no for the shipping vendor (vendors_type must be 3)',
    start_vendor_no INT(6) NOT NULL COMMENT 'Foreign key to VENDOR.no for the vendor being shipped from',
    end_vendor_no INT(6) NOT NULL COMMENT 'Foreign key to the VENDOR.no for the vendor being shipped to',
    shipment_duration INT(1) DEFAULT 1 COMMENT 'Duration in whole days shipment will take',
    price FLOAT(5,5) NOT NULL COMMENT 'Price in US dollars per shipment lbs (down to 5 decimal places)',
    is_flat_rate TINYINT(1) DEFAULT 0 COMMENT '1 if is flat rate regardless of weight, 0 if price is by lbs',
    INDEX (shipping_vendor_no),
    INDEX (start_vendor_no),
    INDEX (end_vendor_no),
    FOREIGN KEY (shipping_vendor_no) REFERENCES VENDOR (no),
    FOREIGN KEY (start_vendor_no) REFERENCES VENDOR (no),
    FOREIGN KEY (end_vendor_no) REFERENCES VENDOR (no)  
) ENGINE=InnoDB;

ข้อคิดสำคัญ

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

ด้วยการปฏิบัติตามแนวทางเหล่านี้ คุณสามารถสร้างตารางของคุณด้วยคีย์ต่างประเทศหลายตัวได้อย่างมีประสิทธิภาพ และหลีกเลี่ยงข้อผิดพลาดที่พบบ่อยที่เกี่ยวข้องกับข้อกำหนดคีย์ต่างประเทศ ขอให้โชคดีในการทำงานกับ MySQL ของคุณและสนุกกับการเขียนโค้ด!