ตามข้อ จำกัด ของรูทีนและทริกเกอร์ที่เก็บไว้ไม่สามารถใช้ไดนามิก sql ได้ (ข้อ จำกัด ถูกยกขึ้นสำหรับโพรซีเดอร์ที่เก็บในเวอร์ชัน 5.0.13 และใหม่กว่า) เหตุใดจึงมีข้อ จำกัด นี้ และทำไมต้องยกมันสำหรับขั้นตอน แต่ไม่ใช่ฟังก์ชั่นหรือทริกเกอร์?
ตามข้อ จำกัด ของรูทีนและทริกเกอร์ที่เก็บไว้ไม่สามารถใช้ไดนามิก sql ได้ (ข้อ จำกัด ถูกยกขึ้นสำหรับโพรซีเดอร์ที่เก็บในเวอร์ชัน 5.0.13 และใหม่กว่า) เหตุใดจึงมีข้อ จำกัด นี้ และทำไมต้องยกมันสำหรับขั้นตอน แต่ไม่ใช่ฟังก์ชั่นหรือทริกเกอร์?
คำตอบ:
แค่ได้ยินคำถามทำให้ฉันนึกถึงสองด้าน:
ASPECT # 1: ฟังก์ชันควรจะเป็น DETERMINISTIC
หากเป็นเช่นนี้นี่ก็หมายความว่าฟังก์ชั่นควรแสดงข้อมูลการส่งคืนเดียวกันอย่างสม่ำเสมอสำหรับชุดของพารามิเตอร์ที่กำหนดไม่มีสิ่งสำคัญเมื่อคุณเรียกฟังก์ชั่น
ทีนี้ลองนึกภาพฟังก์ชั่นที่สร้างคำตอบที่แตกต่างออกไปเพราะการรวบรวมข้อมูลในช่วงเวลาต่าง ๆ ของวันตาม SQL แบบคงที่ในฟังก์ชั่น เรียกได้ว่ายังคงสามารถพิจารณา DETERMINISTIC ได้หากคุณสอบถามชุดตารางและคอลัมน์เดียวกันทุกครั้งโดยกำหนดพารามิเตอร์ชุดเดียวกัน
ถ้าคุณสามารถเปลี่ยนตารางพื้นฐานของฟังก์ชันผ่าน Dynamic SQL ได้ล่ะ คุณกำลังละเมิดคำจำกัดความของฟังก์ชัน DETERMINISTIC
โปรดสังเกตว่า MySQL เพิ่มตัวเลือกนี้ใน /etc/my.cnf
log-bin-trust-function-creators
แม้ว่านี่จะเป็นการพูดเกินจริง แต่ก็อนุญาตให้ฟังก์ชั่นได้รับอนุญาตให้เขียนข้อมูลลงในบันทึกไบนารีโดยไม่บังคับใช้คุณสมบัติ DETERMINISTIC อย่างเคร่งครัด
ASPECT # 2: ทริกเกอร์ควรสามารถย้อนกลับได้
โดยพื้นฐานแล้วคุณจะมีข้อมูลที่เพิ่มขึ้นแบบจตุรัส กระบวนการจัดการการย้อนกลับของ SQL ด้วยทริกเกอร์ที่ไม่ใช่แบบ DETERMINISTIC จะมีความซับซ้อนแบบอโหสิกรรมเพื่อพูดน้อยที่สุด
ในแง่ของทั้งสองด้านนี้ฉันมั่นใจว่านักพัฒนา MySQL คิดถึงสิ่งเหล่านี้และยกเลิกพวกเขาอย่างรวดเร็วโดยกำหนดข้อ จำกัด
ดังนั้นทำไมยกข้อ จำกัด สำหรับขั้นตอน? พูดง่ายๆก็คือไม่ต้องกังวลกับคุณสมบัติของ DETERMINISTIC หรือการย้อนกลับ
นี่เป็นคำถามที่ดี แต่ฉันไม่รู้คำตอบ ฉันคิดว่าสิ่งนี้จะต้องมีทีมงาน internals แต่ฉันไม่รู้ว่าพวกเขาจะยิ่งใหญ่ในเว็บไซต์นี้ ในระหว่างนี้ฉันสามารถช่วยคุณสรุปคำตอบได้
สำหรับผู้เริ่มฉันเห็นสิ่งนี้:
ทริกเกอร์แคชไม่ตรวจจับเมื่อข้อมูลเมตาของวัตถุต้นแบบเปลี่ยนแปลงไป หากทริกเกอร์ใช้ตารางและตารางมีการเปลี่ยนแปลงนับตั้งแต่ทริกเกอร์ถูกโหลดลงในแคชทริกเกอร์จะทำงานโดยใช้เมทาดาทาที่ล้าสมัย
ซึ่งทำให้ฉันคิดว่ามันมีส่วนเกี่ยวข้องกับมัน มันจะไม่คอมไพล์ SQL อีกครั้งถ้ามันไม่ได้ตรวจสอบเมตาดาต้าด้วยซ้ำ ซึ่งหมายความว่าเป็นเรื่องของเครื่องยนต์
ในทำนองเดียวกันเมื่อฉันอ่านบล็อกนี้ฉันก็คิดเหมือนกัน (เอ็นจิ้น):
เพื่อป้องกันปัญหาการมีปฏิสัมพันธ์ระหว่างเธรดเซิร์ฟเวอร์เมื่อไคลเอ็นต์ออกคำสั่งเซิร์ฟเวอร์จะใช้สแน็ปช็อตของรูทีนและทริกเกอร์ที่พร้อมใช้งานสำหรับการดำเนินการของคำสั่ง นั่นคือเซิร์ฟเวอร์จะคำนวณรายการของโพรซีเดอร์ฟังก์ชันและทริกเกอร์ที่อาจใช้ระหว่างการดำเนินการของคำสั่งโหลดคำสั่งนั้นแล้วดำเนินการเพื่อดำเนินการคำสั่ง ซึ่งหมายความว่าในขณะที่คำสั่งดำเนินการก็จะไม่เห็นการเปลี่ยนแปลงในการปฏิบัติตามหัวข้ออื่น ๆ
ดังนั้นทั้งหมดฉันไม่แน่ใจทั้งหมดว่าทำไมพวกเขาถึงไม่อนุญาต แต่ฉันเดาได้ ขออภัยที่ฉันไม่สามารถช่วยคุณได้มากกว่านี้ฉันเปิดโอกาสที่จะพูดเรื่องนี้เพิ่มเติม ดีที่สุดคือการหวัง MySQL devs ที่ใช้งานอยู่เมื่อเราออกจากเบต้าส่วนตัว)
ส่วนใหญ่เป็นเพราะความปลอดภัย ข้อยกเว้นสำหรับโพรซีเดอร์คือไดนามิก SQL ภายในโพรซีเดอร์สามารถกำหนดบริบทความปลอดภัยของผู้ใช้ที่ดำเนินการได้ ซึ่งหมายความว่าแม้ว่าเอ็นจิ้นจะไม่ทราบว่ากำลังจะถูกดำเนินการ แต่สามารถตรวจสอบให้แน่ใจว่าผู้ใช้ได้รับอนุญาตให้เข้าถึงวัตถุที่อ้างอิง
นอกเหนือจากนั้นคุณสามารถยกประเด็นที่น่าเกลียดของสิ่งที่อาจเกิดขึ้นได้ถ้าอนุญาต