หลักการ: 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';