Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> MySQL

อ้างอิง Primary Key เป็น Foreign Key หลายตารางใน MySQL

หลักการ: 1 ตารางหลัก (Parent) → หลายตารางลูก (Children)

Primary Key ของตารางหลัก สามารถถูกอ้างอิงเป็น Foreign Key โดยตารางลูกได้หลายตาราง

ไวยากรณ์ ALTER TABLE ADD FOREIGN KEY

ALTER TABLE child_table
ADD CONSTRAINT constraint_name
FOREIGN KEY (child_column)
REFERENCES parent_table (parent_column);

ตัวอย่าง: demo65 (Parent) → demo66 (Child)

-- ตารางหลัก
CREATE TABLE demo65 (
    id INT NOT NULL PRIMARY KEY,
    name VARCHAR(20)
);

-- ตารางลูก
CREATE TABLE demo66 (
    user_id INT NOT NULL PRIMARY KEY,
    address VARCHAR(200)
);

-- เพิ่ม Foreign Key
ALTER TABLE demo66
ADD CONSTRAINT `id_fk`
FOREIGN KEY (`user_id`)
REFERENCES demo65(id);

ตรวจสอบด้วย SHOW CREATE TABLE

SHOW CREATE TABLE demo66;
CREATE TABLE `demo66` (
  `user_id` int NOT NULL,
  `address` varchar(200) DEFAULT NULL,
  PRIMARY KEY (`user_id`),
  CONSTRAINT `id_fk` FOREIGN KEY (`user_id`) REFERENCES `demo65` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4

เพิ่มตารางลูกอีก (demo67)

CREATE TABLE demo67 (
    emp_id INT NOT NULL PRIMARY KEY,
    department VARCHAR(50),
    CONSTRAINT `fk_demo65` FOREIGN KEY (`emp_id`) REFERENCES `demo65` (`id`)
);

กฎสำคัญของ Foreign Key

  • ตารางทั้งสองต้องใช้ Engine InnoDB (MyISAM ไม่รองรับ FK)
  • ชนิดข้อมูลของ PK และ FK ต้องตรงกันทุกประการ (INT ↔ INT, VARCHAR(20) ↔ VARCHAR(20))
  • คอลัมน์ PK ต้องมี INDEX (PK เองก็เป็น INDEX แล้ว)
  • ค่าที่ INSERT ใน FK ต้องมีอยู่ใน PK แล้ว (Referential Integrity)

ON DELETE / ON UPDATE Actions

ALTER TABLE demo66
ADD CONSTRAINT `id_fk`
FOREIGN KEY (`user_id`) REFERENCES `demo65` (`id`)
ON DELETE CASCADE      -- ลบ Parent → ลบ Child ด้วย
ON UPDATE CASCADE;     -- อัปเดต PK → อัปเดต FK ด้วย
Actionพฤติกรรม
CASCADEแพร่กระจายการเปลี่ยนแปลง
SET NULLตั้งค่า FK เป็น NULL (ต้อง nullable)
RESTRICT / NO ACTIONป้องกันการลบ/อัปเดต Parent (ค่าเริ่มต้น)
SET DEFAULTตั้งค่าเป็น DEFAULT (นادرๆ)

ตรวจสอบ Foreign Keys ที่มีอยู่

SELECT 
    TABLE_NAME, COLUMN_NAME, CONSTRAINT_NAME, REFERENCED_TABLE_NAME, REFERENCED_COLUMN_NAME
FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE
WHERE REFERENCED_TABLE_NAME = 'demo65';