ใครก็ตามที่ได้พัฒนาเว็บแอปพลิเคชันที่ขับเคลื่อนด้วยฐานข้อมูลขนาดเล็กโดยใช้ MySQL จะรู้ดีว่าการสร้าง การดึงข้อมูล การอัปเดต และการลบตารางในฐานข้อมูลเชิงสัมพันธ์เป็นกระบวนการที่ค่อนข้างง่าย ตามทฤษฎี ตราบใดที่คุณเชี่ยวชาญในการใช้คำสั่ง SQL ทั่วไปและคุ้นเคยกับภาษาสคริปต์ฝั่งเซิร์ฟเวอร์ที่คุณเลือกใช้ ก็เพียงพอที่จะจัดการกับการดำเนินการต่างๆ ที่จำเป็นในตาราง MySQL โดยเฉพาะอย่างยิ่งเมื่อคุณใช้ MyISAM ที่รวดเร็ว เอ็นจิ้นฐานข้อมูลเมื่อ แต่ถึงแม้ในกรณีที่ง่ายที่สุด สิ่งต่างๆ ก็ซับซ้อนกว่าที่เราคิด ด้านล่างเราใช้ตัวอย่างทั่วไปเพื่อแสดงให้เห็น สมมติว่าคุณใช้งานบล็อกไซต์ที่คุณอัปเดตเกือบทุกวัน และไซต์ดังกล่าวอนุญาตให้ผู้เยี่ยมชมแสดงความคิดเห็นในโพสต์ของคุณ
ในกรณีนี้ สคีมาฐานข้อมูลของเราควรมีตาราง MyISAM อย่างน้อยสองตาราง ตารางหนึ่งสำหรับจัดเก็บโพสต์บนบล็อกของคุณ และอีกตารางหนึ่งเพื่อจัดการกับความคิดเห็นของผู้เยี่ยมชม แน่นอนว่ามีความสัมพันธ์แบบหนึ่งต่อกลุ่มระหว่างสองตารางนี้ ดังนั้นเราจึงจำเป็นต้องกำหนดคีย์นอกในตารางที่สอง เพื่อให้สามารถรักษาความสมบูรณ์ของฐานข้อมูลได้เมื่อมีการอัปเดตหรือลบแถวข้อมูล
สำหรับแอปพลิเคชันข้างต้น ไม่เพียงแต่การรักษาความสมบูรณ์ของตารางทั้งสองจะเป็นความท้าทายร้ายแรงเท่านั้น แต่ปัญหาที่ใหญ่ที่สุดก็คือ เราต้องรักษาความสมบูรณ์ของตารางทั้งสองในระดับแอปพลิเคชัน นี่คือแนวทางที่ใช้ระหว่างการพัฒนาสำหรับโครงการเว็บส่วนใหญ่ที่ไม่จำเป็นต้องใช้ธุรกรรม เนื่องจากตาราง MyISAM ให้ประสิทธิภาพที่ยอดเยี่ยม
แน่นอนว่าสิ่งนี้ต้องแลกมาด้วยต้นทุนเช่นกัน ดังที่ฉันได้กล่าวไว้ก่อนหน้านี้ แอปพลิเคชันจะต้องรักษาความสมบูรณ์และความสอดคล้องของฐานข้อมูล ซึ่งหมายถึงการใช้ตรรกะการเขียนโปรแกรมที่ซับซ้อนมากขึ้นเพื่อจัดการความสัมพันธ์ระหว่างตารางต่างๆ แม้ว่าการเข้าถึงฐานข้อมูลสามารถทำให้ง่ายขึ้นผ่านการใช้เลเยอร์นามธรรมและโมดูล ORM เนื่องจากจำนวนตารางข้อมูลที่แอปพลิเคชันต้องการเพิ่มขึ้น ตรรกะที่จำเป็นในการจัดการตารางเหล่านี้จะซับซ้อนมากขึ้นอย่างไม่ต้องสงสัย
ดังนั้น สำหรับ MySQL มีวิธีการประมวลผลคีย์ต่างประเทศระดับฐานข้อมูลเพื่อช่วยรักษาความสมบูรณ์ของฐานข้อมูลหรือไม่ โชคดีที่คำตอบคือใช่! MySQL ยังสามารถรองรับตาราง InnoDB ได้อีกด้วย ทำให้เราใช้วิธีที่ง่ายมากในการจัดการกับข้อจำกัดของคีย์ต่างประเทศ คุณลักษณะนี้ช่วยให้เราสามารถกระตุ้นการดำเนินการบางอย่าง เช่น การอัปเดตและการลบแถวข้อมูลบางแถวในตารางเพื่อรักษาความสัมพันธ์ที่กำหนดไว้ล่วงหน้า
ทุกอย่างมีข้อดีและข้อเสีย และข้อเสียหลักของการใช้ตาราง InnoDB ก็คือตารางจะช้ากว่า MyISAM โดยเฉพาะในแอปพลิเคชันขนาดใหญ่ที่ต้องสอบถามตารางจำนวนมาก โชคดีที่ตาราง MyISAM ใน MySQL เวอร์ชันใหม่กว่ายังรองรับข้อจำกัดของคีย์ต่างประเทศด้วย
บทความนี้จะแนะนำวิธีการใช้ข้อจำกัดของคีย์ต่างประเทศกับตาราง InnoDB นอกจากนี้ เราจะใช้คลาสนามธรรม MySQL ที่ใช้ PHP เพื่อสร้างโค้ดตัวอย่างที่เกี่ยวข้อง แน่นอนว่า คุณยังสามารถใช้ภาษาฝั่งเซิร์ฟเวอร์อื่นๆ ที่คุณชื่นชอบได้ ตอนนี้ เราเริ่มแนะนำวิธีการใช้ข้อจำกัดคีย์ต่างประเทศกับ MySQL
เมื่อใดจึงควรใช้ข้อจำกัดของคีย์ต่างประเทศ
พูดตามตรง เมื่อใช้ตาราง InnoDB ใน MySQL คุณไม่จำเป็นต้องใช้ข้อจำกัดของคีย์ต่างประเทศ อย่างไรก็ตาม เพื่อวัตถุประสงค์ของข้อจำกัดของคีย์ต่างประเทศในบางสถานการณ์ เราจะใช้โค้ดของตัวอย่างที่กล่าวถึงก่อนหน้านี้เพื่ออธิบายโดยละเอียด ประกอบด้วยตาราง MyISAM สองตาราง ใช้สำหรับจัดเก็บโพสต์ในบล็อกและความคิดเห็น
เมื่อกำหนดสคีมาฐานข้อมูล เราจำเป็นต้องสร้างความสัมพันธ์แบบหนึ่งต่อกลุ่มระหว่างสองตารางโดยการสร้างคีย์นอกในตารางที่เก็บความคิดเห็นเพื่อแมปแถวข้อมูล (เช่น ความคิดเห็น) กับบทความเฉพาะของบล็อก นี่คือโค้ด SQL พื้นฐานในการสร้างตาราง MyISAM ตัวอย่าง:
วางตารางถ้ามี `ทดสอบ`.`บล็อก`;
สร้างตาราง `ทดสอบ`.`บล็อก` (
`id` INT (10) ไม่ได้ลงนาม AUTO_INCREMENT,
`ชื่อเรื่อง` ข้อความ
`เนื้อหา` ข้อความ
`ผู้เขียน` VARCHAR (45) ค่าเริ่มต้น NULL,
รหัสไพรโรส (`id`)
) ENGINE=ชุดคำสั่งเริ่มต้นของ MyISAM=utf8;
วางตารางหากมี `ทดสอบ`.`ความคิดเห็น`;
สร้างตาราง `ทดสอบ`.`ความคิดเห็น` (
`id` INT (10) ไม่ได้ลงนาม AUTO_INCREMENT,
`blog_id` INT(10) ค่าเริ่มต้นที่ไม่ได้ลงนาม NULL,
ข้อความ 'ความคิดเห็น'
`ผู้เขียน` VARCHAR (45) ค่าเริ่มต้น NULL,
รหัสไพรโรส (`id`)
) ENGINE=ชุดคำสั่งเริ่มต้นของ MyISAM=utf8;
ด้านบน เราเพิ่งกำหนดตาราง MyISAM สองตาราง ซึ่งสร้างชั้นข้อมูลของแอปพลิเคชันบล็อก อย่างที่คุณเห็น ตารางแรกเรียกว่าบล็อก ประกอบด้วยฟิลด์ที่ชัดเจนซึ่งใช้เพื่อจัดเก็บ ID ชื่อเรื่อง และเนื้อหาของแต่ละโพสต์ในบล็อก และสุดท้ายคือผู้เขียน ตารางที่สองชื่อความคิดเห็น ซึ่งใช้เพื่อจัดเก็บความคิดเห็นที่เกี่ยวข้องกับโพสต์ในบล็อกแต่ละรายการ โดยจะใช้ ID ของโพสต์ในบล็อกเป็นคีย์นอกเพื่อสร้างความสัมพันธ์แบบหนึ่งต่อกลุ่ม
จนถึงตอนนี้ งานของเราเป็นเรื่องง่ายเพราะเราสร้างตาราง MyISAM แบบง่ายๆ เพียงสองตารางเท่านั้น ต่อไป สิ่งที่เราต้องการทำคือเติมระเบียนลงในตารางเหล่านี้เพื่อสาธิตเพิ่มเติมว่าควรทำอะไรในตารางอื่นเมื่อรายการถูกลบในตารางแรก
อัปเดตและรักษาความสมบูรณ์ของฐานข้อมูล
ในส่วนก่อนหน้านี้ เราได้สร้างตาราง MyISAM สองตารางเพื่อทำหน้าที่เป็นชั้นข้อมูลของแอปพลิเคชันบล็อก แน่นอนว่าบทนำข้างต้นยังคงง่ายมาก และเราจำเป็นต้องพูดคุยกันเพิ่มเติม เมื่อต้องการทำเช่นนี้ เราจะเติมข้อมูลตารางเหล่านี้ด้วยระเบียนบางส่วนโดยใช้คำสั่ง SQL ดังต่อไปนี้:
แทรกลงในบล็อก (id, ชื่อเรื่อง, เนื้อหา, ผู้แต่ง) ค่า (NULL, 'ชื่อของรายการบล็อกแรก', 'เนื้อหาของรายการบล็อกแรก', 'เอียน')
แทรกความคิดเห็นลงในความคิดเห็น (id, blog_id, ความคิดเห็น, ผู้เขียน) ค่า (NULL, 1, 'การแสดงความคิดเห็นรายการบล็อกแรก', 'Susan Norton'), (NULL, 1, 'การแสดงความคิดเห็นรายการบล็อกแรก', 'Rose Wilson')
โค้ดด้านบนจำลองสถานการณ์ที่ผู้อ่าน Susan และ Rose แสดงความคิดเห็นในบล็อกแรกของเรา สมมติว่าตอนนี้เราต้องการอัปเดตบล็อกแรกด้วยโพสต์อื่น แน่นอนว่าสถานการณ์นี้เป็นไปได้
ในกรณีนี้ เพื่อรักษาความสอดคล้องของฐานข้อมูล ตารางความคิดเห็นจะต้องได้รับการอัปเดตตามนั้นด้วย ไม่ว่าจะด้วยตนเองหรือโดยแอปพลิเคชันที่ประมวลผลชั้นข้อมูล สำหรับตัวอย่างนี้ เราจะใช้คำสั่ง SQL เพื่อทำการอัพเดตให้เสร็จสิ้นดังนี้:
อัปเดตบล็อก SET id = 2, title = 'ชื่อของรายการบล็อกแรก', content = 'เนื้อหาของรายการบล็อกแรก', ผู้แต่ง = 'John Doe' WHERE id = 1
อัปเดตความคิดเห็น SET blog_id = 2 โดยที่ blod_id = 1
ตามที่กล่าวไว้ก่อนหน้านี้ เนื่องจากเนื้อหาของรายการข้อมูลของบล็อกแรกได้รับการอัปเดต ตารางความคิดเห็นจึงต้องสะท้อนถึงการเปลี่ยนแปลงนี้ด้วย แน่นอนว่า ในความเป็นจริงแล้ว การดำเนินการอัปเดตนี้ควรจะเสร็จสิ้นที่ชั้นแอปพลิเคชันแทนที่จะดำเนินการด้วยตนเอง ซึ่งหมายความว่าจะต้องปรับใช้ตรรกะนี้โดยใช้ภาษาฝั่งเซิร์ฟเวอร์
เพื่อให้การดำเนินการนี้เสร็จสมบูรณ์ PHP สามารถใช้กระบวนการย่อยง่ายๆ แต่ในความเป็นจริง หากใช้ข้อจำกัดของคีย์ต่างประเทศ การดำเนินการอัปเดตของตารางความคิดเห็นสามารถมอบหมายให้กับฐานข้อมูลได้
ตามที่กล่าวไว้ก่อนหน้าในบทความ ตาราง InnoDB MySQL ให้การสนับสนุนฟังก์ชันนี้ได้อย่างราบรื่น ดังนั้นในส่วนหลัง เราจะใช้ข้อจำกัดของคีย์ต่างประเทศเพื่อสร้างโค้ดตัวอย่างก่อนหน้านี้ขึ้นมาใหม่
การอัพเดตแบบเรียงซ้อนไปยังฐานข้อมูล
ด้านล่างนี้ เราจะปรับโครงสร้างโค้ดตัวอย่างก่อนหน้านี้โดยใช้ข้อจำกัดของคีย์ภายนอกและตาราง InnoDB (แทนประเภท MyISAM เริ่มต้น) เมื่อต้องการทำเช่นนี้ ขั้นแรกกำหนดตารางตัวอย่างสองตารางใหม่เพื่อให้สามารถใช้เครื่องมือฐานข้อมูลเฉพาะได้ เมื่อต้องการทำเช่นนี้ คุณสามารถใช้โค้ด SQL ดังต่อไปนี้:
วางตารางถ้ามี `ทดสอบ`.`บล็อก`;
สร้างตาราง `ทดสอบ`.`บล็อก` (
`id` INT (10) ไม่ได้ลงนาม AUTO_INCREMENT,
`ชื่อเรื่อง` ข้อความ
`เนื้อหา` ข้อความ
`ผู้เขียน` VARCHAR (45) ค่าเริ่มต้น NULL,
รหัสไพรโรส (`id`)
) ENGINE=อักขระเริ่มต้นของ InnoDB=utf8;
วางตารางหากมี `ทดสอบ`.`ความคิดเห็น`;
สร้างตาราง `ทดสอบ`.`ความคิดเห็น` (
`id` INT (10) ไม่ได้ลงนาม AUTO_INCREMENT,
`blog_id` INT(10) ค่าเริ่มต้นที่ไม่ได้ลงนาม NULL,
ข้อความ 'ความคิดเห็น'
`ผู้เขียน` VARCHAR (45) ค่าเริ่มต้น NULL,
รหัสไพรโรส (`id`)
คีย์ `blog_ind` (`blog_id`)
ข้อ จำกัด `comments_ibfk_1` คีย์ต่างประเทศ (`blog_id`) การอ้างอิง `บล็อก` (`id`) ในการอัปเดต CASCADE
) ENGINE=อักขระเริ่มต้นของ InnoDB=utf8;
ข้อแตกต่างที่ชัดเจนระหว่างโค้ดที่นี่และโค้ดก่อนหน้าคือตอนนี้ทั้งสองตารางใช้เครื่องมือจัดเก็บข้อมูล InnoDB ดังนั้นจึงสามารถรองรับข้อจำกัดของคีย์ต่างประเทศได้ นอกจากนี้เรายังต้องใส่ใจกับโค้ดที่กำหนดตารางความคิดเห็นด้วย:
ข้อ จำกัด `comments_ibfk_1` คีย์ต่างประเทศ (`blog_id`) การอ้างอิง `บล็อก` (`id`) ในการอัปเดต CASCADE
ในความเป็นจริง คำสั่งนี้จะแจ้งให้ MySQL ทราบว่าเมื่อมีการอัปเดตตารางบล็อก ค่าของคีย์ต่างประเทศ blog_id ในตารางความคิดเห็นก็ควรได้รับการอัปเดตด้วย กล่าวอีกนัยหนึ่ง สิ่งที่ทำที่นี่คือเพื่อให้ MySQL รักษาความสมบูรณ์ของฐานข้อมูลในลักษณะแบบเรียงซ้อน ซึ่งหมายความว่าเมื่อมีการอัปเดตบล็อก ความคิดเห็นที่เชื่อมต่อกับบล็อกจะต้องสะท้อนถึงการเปลี่ยนแปลงนี้ทันที สิ่งสำคัญคือการนำฟังก์ชันนี้ไปใช้ . ไม่ได้ทำที่ชั้นแอปพลิเคชัน
ตาราง MySQL สองตัวอย่างได้ถูกกำหนดไว้แล้ว ในตอนนี้ การอัปเดตทั้งสองตารางนี้ทำได้ง่ายเพียงแค่เรียกใช้คำสั่ง UPDATE ดังที่แสดงด้านล่าง:
"อัปเดตบล็อก SET id = 2, title = 'ชื่อของรายการบล็อกแรก', content = 'เนื้อหาของรายการบล็อกแรก', ผู้แต่ง = 'John Doe' WHERE id = 1"
ตามที่กล่าวไว้ข้างต้น เราไม่จำเป็นต้องอัปเดตตารางความคิดเห็น เนื่องจาก MySQL จะจัดการสิ่งนี้โดยอัตโนมัติ นอกจากนี้ คุณสามารถให้ MySQL ไม่ต้องทำอะไรเลยเมื่อพยายามอัปเดตแถวในตารางบล็อก โดยลบส่วน "ON UPDATE" ของแบบสอบถามออก หรือระบุ "NO ACTION" และ "RESTRICT" แน่นอน คุณสามารถปล่อยให้ MySQL ทำอย่างอื่นได้ ซึ่งจะแนะนำในบทความต่อๆ ไป
จากการแนะนำข้างต้น ฉันคิดว่าทุกคนมีความเข้าใจที่ชัดเจนเกี่ยวกับวิธีใช้ข้อจำกัดของคีย์ต่างประเทศร่วมกับตาราง InnoDB ใน MySQL แน่นอน คุณยังสามารถเขียนโค้ดเพิ่มเติมได้ทันทีเพื่อทำความเข้าใจฟังก์ชันฐานข้อมูลที่สะดวกสบายนี้ให้ลึกซึ้งยิ่งขึ้น