อัปเดตล่าสุด April 20, 2024
Foreign Key (FK) คืออะไร
Foreign Key (FK) คือ คอลัมน์หรือฟีลด์ในตารางที่ใช้สร้างความสัมพันธ์ระหว่างข้อมูลทั้งสองตารางเข้าด้วยกัน (หรือ Join กันนั่นเอง)โดย FK (ทำหน้าที่เป็นตารางลูกหรือ Child Table) จะอ้างอิงไปยัง Primary Key (PK) ที่จะทำหน้าที่เสมือนตารางแม่ (Parent Table) โดยปกติแล้วจะเป็นการเชื่อมความสัมพันธ์แบบ 1-to-M (One-to-Many หรือ Many-to-One)
ตัวอย่างการใช้งาน FK
ผมจะขอยกตัวอย่างฐานข้อมูลบางส่วนของเว็บ E-commerce โดยจะมีการสร้างตาราง Buyer, Order และ Order Item ซึ่งเป็นตารางของเว็บขายสินค้าโดยทั่วไปเลยครับ จะเห็นว่า 1 buyer สามารถมีได้หลาย orders และ 1 order ก็ยังมีได้หลาย items เช่นกัน (ก็คือ 1-to-M) จากภาพด้านล่างแสดงผลไดอะแกรม (ใช้ dbdiagram.io)
ไดอะแกรม
ตาราง Buyer
buyer_id (PK) | buyer_name |
1 | Som Jomson |
2 | Salid Narak |
3 | Korat Sudloh |
ตาราง Order
order_id (PK) | order_date | total_price | buyer_id (FK) |
1 | 2023-10-28 | 2 | 1 |
2 | 2023-10-28 | 2 | 2 |
3 | 2023-10-28 | 5 | 3 |
order_item_id (PK) | order_id (FK) | item_name | quantity | price |
1 | 1 | อาหารเม็ด | 2 | 300.00 |
2 | 1 | อาหารเปียก | 3 | 150.75 |
3 | 2 | อาหารเปียก | 5 | 251.25 |
4 | 3 | ขนมแมวเลีย | 9 | 180.00 |
5 | 3 | ขนมแมวเลีย | 8 | 160.00 |
จะเห็นว่าเราจะ join ตารางด้วยคอลัมน์ FK ไปที่คอลัมน์ PK หรือ Primary Key (คีย์หลัก) และแน่นอนว่า PK นั้นต้องเป็น ID ที่ unique คือต้องมีความเฉพาะเจาะจง ห้ามซ้ำกันเด็ดขาด (โดยส่วนใหญ่แล้วจะใช้ชนิดข้อมูลแบบ Int และเงื่อนไข Auto-increment)
เมื่อนำไปเขียนเป็นโค้ด SQL
-- สร้างตาราง "Buyer"CREATE TABLE Buyer (buyer_id INT AUTO_INCREMENT NOT NULL PRIMARY KEY,buyer_name VARCHAR(255) NOT NULL);-- สร้างตาราง "Order"CREATE TABLE Order (order_id INT AUTO_INCREMENT NOT NULL PRIMARY KEY,order_date DATE NOT NULL,total_price DECIMAL(10, 2) NOT NULL,buyer_id INT NOT NULL,FOREIGN KEY (buyer_id) REFERENCES Buyer(buyer_id));-- สร้างตาราง "Order Items"CREATE TABLE Order_Items (order_item_id INT AUTO_INCREMENT NOT NULL PRIMARY KEY,order_id INT NOT NULL,item_name VARCHAR(255) NOT NULL,quantity INT NOT NULL,price DECIMAL(10, 2) NOT NULL,FOREIGN KEY (order_id) REFERENCES Order(order_id));
บทความแนะนำอ่านเพิ่มเติม: ภาษา SQL คืออะไร รวมคำสั่ง SQL เบื้องต้น
เงื่อนไข ON DELETE
แล้วถ้าต้องมีการลบแถวหรือ Record ภายในตาราง Primary ล่ะ อะไรจะเกิดขึ้น ?
ตามปกติแล้วเมื่อกำหนด FOREIGN KEY
จะไม่สามารถลบข้อมูลใน Primary Key ได้ ดังนั้นต้องมีการกำหนด Constraint (เงื่อนไข) ก่อนว่า เมื่อกดลบแล้วจะมีอะไรเกิดขึ้นต่อไป เวลานำไปใช้งานก็ลองเลือกเงื่อนไขที่เข้ากับบริบทของ use case จริงกันด้วยนะครับ ซึ่งคำสั่ง ON DELETE
ก็มีอยู่ทั้งหมด 5 ตัว ดังนี้
คำสั่ง ON DELETE CASCADE
เป็นคำสั่งที่เมื่อเราลบ ID ตัวใดตัวหนึ่งของ PRIMARY KEY
ออกแล้ว ข้อมูลในทุก ๆ Row ของ ID นั้น ๆ จะถูกลบตามไปด้วยเช่นกัน
ถ้าใครที่ใช้ Back-end เฟรมเวิร์ค ตัวอย่างเช่นในภาพด้านล่างคือ Django framework จะเห็นว่ามีการกำหนดเงื่อนไข on_delete ใน FK ตามแนวคิดที่ได้อธิบายไปข้างต้นเลยครับ (แต่ที่เห็นเขียนแปลกจาก SQL ไปบ้างเพราะว่าเป็นการเขียนในรูปแบบ ORM: Object Relational Mapping)
ใน Django Model มีการกำหนด FK และใน FK มีการกำหนด attribute อย่าง on_delete
ปล.ในคอร์สเรียนพัฒนาเว็บด้วย Python (Django) เราก็มีสอน FK ด้วยครับ
คำสั่ง ON DELETE RESTRICT
เป็นคำสั่งที่ไม่อนุญาตให้มีการลบแถว (Record)ใด ๆ ก็ตามในตารางที่เป็น Primary Table
คำสั่ง ON DELETE NO ACTION
เป็นคำสั่งที่ป้องกันการลบแถวใน Primary Table คล้ายกับ RESTRICT
มาก ๆ เลยครับ เพื่อน ๆ อาจจะลองเข้าไปอ่านเพิ่มใน PostgreSQL Doc เพิ่มเติมได้
คำสั่ง ON DELETE SET NULL
เป็นคำสั่งที่ชัดเจนตามชื่อเลยครับ เมื่อมีการลบแถวใน Primary Table ค่าจะเปลี่ยนเป็น Null ทันที
คำสั่ง ON DELETE SET DEFAULT
เป็นคำสั่งที่ค่อนข้างคล้ายกับ Null คือเมื่อมีการลบแถวของ Primary Table ค่าจะถูกคืนกลับไปเป็นค่าเริ่มต้น (Default) ซึ่งถ้าหากจะใช้งานคำสั่งนี้ เราจะต้องกำหนดค่า Default ไว้ก่อนครับ
ประโยชน์ของ Foreign Key ?
ก็จบไปแล้วครับสำหรับแนวคิดของ Foreign Key และตัวอย่างการใช้งานจริง หวังว่าจะทำให้เพื่อน ๆ ที่อ่าน มองภาพรวมและสามารถนำแนวคิดและการออกแบบในบทความนี้ไปประยุกต์ใช้งานจริงได้ครับ
เปิดโลกการเขียนโปรแกรมและ Software Development ด้วย online courses ที่จะพาคุณอัพสกิลและพัฒนาสู่การเป็นมืออาชีพ เรียนออนไลน์ เรียนจากที่ไหนก็ได้ พร้อมซัพพอร์ตหลังเรียน
คอร์สเรียนเขียนโปรแกรม