SQL แบบไดนามิกใน MySQL จัดเก็บเป็นประจำ


13

ตามข้อ จำกัด ของรูทีนและทริกเกอร์ที่เก็บไว้ไม่สามารถใช้ไดนามิก sql ได้ (ข้อ จำกัด ถูกยกขึ้นสำหรับโพรซีเดอร์ที่เก็บในเวอร์ชัน 5.0.13 และใหม่กว่า) เหตุใดจึงมีข้อ จำกัด นี้ และทำไมต้องยกมันสำหรับขั้นตอน แต่ไม่ใช่ฟังก์ชั่นหรือทริกเกอร์?

คำตอบ:


8

แค่ได้ยินคำถามทำให้ฉันนึกถึงสองด้าน:

ASPECT # 1: ฟังก์ชันควรจะเป็น DETERMINISTIC

หากเป็นเช่นนี้นี่ก็หมายความว่าฟังก์ชั่นควรแสดงข้อมูลการส่งคืนเดียวกันอย่างสม่ำเสมอสำหรับชุดของพารามิเตอร์ที่กำหนดไม่มีสิ่งสำคัญเมื่อคุณเรียกฟังก์ชั่น

ทีนี้ลองนึกภาพฟังก์ชั่นที่สร้างคำตอบที่แตกต่างออกไปเพราะการรวบรวมข้อมูลในช่วงเวลาต่าง ๆ ของวันตาม SQL แบบคงที่ในฟังก์ชั่น เรียกได้ว่ายังคงสามารถพิจารณา DETERMINISTIC ได้หากคุณสอบถามชุดตารางและคอลัมน์เดียวกันทุกครั้งโดยกำหนดพารามิเตอร์ชุดเดียวกัน

ถ้าคุณสามารถเปลี่ยนตารางพื้นฐานของฟังก์ชันผ่าน Dynamic SQL ได้ล่ะ คุณกำลังละเมิดคำจำกัดความของฟังก์ชัน DETERMINISTIC

โปรดสังเกตว่า MySQL เพิ่มตัวเลือกนี้ใน /etc/my.cnf

log-bin-trust-function-creators

แม้ว่านี่จะเป็นการพูดเกินจริง แต่ก็อนุญาตให้ฟังก์ชั่นได้รับอนุญาตให้เขียนข้อมูลลงในบันทึกไบนารีโดยไม่บังคับใช้คุณสมบัติ DETERMINISTIC อย่างเคร่งครัด

ASPECT # 2: ทริกเกอร์ควรสามารถย้อนกลับได้

  • คุณลองนึกภาพทริกเกอร์ที่มีพฤติกรรมเหมือนกันทั้งหมดกับฟังก์ชั่นแล้วนำ Dynamic SQL มาผสมกัน
  • คุณลองนึกภาพว่าพยายามใช้MVCC (Multiversion Concurrecy Control)กับ Dynamic SQL หลังจากใช้ MVCC กับตารางฐานที่มีการใช้ทริกเกอร์

โดยพื้นฐานแล้วคุณจะมีข้อมูลที่เพิ่มขึ้นแบบจตุรัส กระบวนการจัดการการย้อนกลับของ SQL ด้วยทริกเกอร์ที่ไม่ใช่แบบ DETERMINISTIC จะมีความซับซ้อนแบบอโหสิกรรมเพื่อพูดน้อยที่สุด

ในแง่ของทั้งสองด้านนี้ฉันมั่นใจว่านักพัฒนา MySQL คิดถึงสิ่งเหล่านี้และยกเลิกพวกเขาอย่างรวดเร็วโดยกำหนดข้อ จำกัด

ดังนั้นทำไมยกข้อ จำกัด สำหรับขั้นตอน? พูดง่ายๆก็คือไม่ต้องกังวลกับคุณสมบัติของ DETERMINISTIC หรือการย้อนกลับ


3
ไม่สามารถ "ซับซ้อนเกินไป" ได้หาก DBMS อื่นสามารถรองรับ MVCC และ SQL แบบไดนามิกได้ดีในทริกเกอร์
a_horse_with_no_name

1
ที่จริงแล้ว @a_horse_with_no_name คุณพูดถูก สำหรับ Oracle และ PostgreSQL คอมเพล็ก ungodly ได้รับการเข้ารหัส +1 สำหรับความคิดเห็นของคุณ MySQL มีแต้มต่อในการจัดการกับเอ็นจิ้นการจัดเก็บข้อมูลที่หลากหลายดังนั้นการย้อนกลับและการกำหนดระดับอาจต้องใช้การซ้อนทับของเอ็นจิ้นการเก็บข้อมูล มันน่ากลัวนิดหน่อย บางทีใครบางคนอาจจะมีความกล้าที่จะผลักดัน "ungodly complex" เข้าไปใน InnoDB โดยสมบูรณ์ สิ่งที่น่าพึงปรารถนายิ่งกว่านั้นคือการสร้างทริกเกอร์เฉพาะของเอ็นจิ้นการจัดเก็บในลักษณะเช่นนั้นมันไม่อนุญาตให้มิกซ์เอ็นจินการเก็บข้อมูลภายในเคียวรีเดียวกัน
RolandoMySQLDBA

5

นี่เป็นคำถามที่ดี แต่ฉันไม่รู้คำตอบ ฉันคิดว่าสิ่งนี้จะต้องมีทีมงาน internals แต่ฉันไม่รู้ว่าพวกเขาจะยิ่งใหญ่ในเว็บไซต์นี้ ในระหว่างนี้ฉันสามารถช่วยคุณสรุปคำตอบได้

สำหรับผู้เริ่มฉันเห็นสิ่งนี้:

ทริกเกอร์แคชไม่ตรวจจับเมื่อข้อมูลเมตาของวัตถุต้นแบบเปลี่ยนแปลงไป หากทริกเกอร์ใช้ตารางและตารางมีการเปลี่ยนแปลงนับตั้งแต่ทริกเกอร์ถูกโหลดลงในแคชทริกเกอร์จะทำงานโดยใช้เมทาดาทาที่ล้าสมัย

ซึ่งทำให้ฉันคิดว่ามันมีส่วนเกี่ยวข้องกับมัน มันจะไม่คอมไพล์ SQL อีกครั้งถ้ามันไม่ได้ตรวจสอบเมตาดาต้าด้วยซ้ำ ซึ่งหมายความว่าเป็นเรื่องของเครื่องยนต์

ในทำนองเดียวกันเมื่อฉันอ่านบล็อกนี้ฉันก็คิดเหมือนกัน (เอ็นจิ้น):

เพื่อป้องกันปัญหาการมีปฏิสัมพันธ์ระหว่างเธรดเซิร์ฟเวอร์เมื่อไคลเอ็นต์ออกคำสั่งเซิร์ฟเวอร์จะใช้สแน็ปช็อตของรูทีนและทริกเกอร์ที่พร้อมใช้งานสำหรับการดำเนินการของคำสั่ง นั่นคือเซิร์ฟเวอร์จะคำนวณรายการของโพรซีเดอร์ฟังก์ชันและทริกเกอร์ที่อาจใช้ระหว่างการดำเนินการของคำสั่งโหลดคำสั่งนั้นแล้วดำเนินการเพื่อดำเนินการคำสั่ง ซึ่งหมายความว่าในขณะที่คำสั่งดำเนินการก็จะไม่เห็นการเปลี่ยนแปลงในการปฏิบัติตามหัวข้ออื่น ๆ

ดังนั้นทั้งหมดฉันไม่แน่ใจทั้งหมดว่าทำไมพวกเขาถึงไม่อนุญาต แต่ฉันเดาได้ ขออภัยที่ฉันไม่สามารถช่วยคุณได้มากกว่านี้ฉันเปิดโอกาสที่จะพูดเรื่องนี้เพิ่มเติม ดีที่สุดคือการหวัง MySQL devs ที่ใช้งานอยู่เมื่อเราออกจากเบต้าส่วนตัว)


1

ส่วนใหญ่เป็นเพราะความปลอดภัย ข้อยกเว้นสำหรับโพรซีเดอร์คือไดนามิก SQL ภายในโพรซีเดอร์สามารถกำหนดบริบทความปลอดภัยของผู้ใช้ที่ดำเนินการได้ ซึ่งหมายความว่าแม้ว่าเอ็นจิ้นจะไม่ทราบว่ากำลังจะถูกดำเนินการ แต่สามารถตรวจสอบให้แน่ใจว่าผู้ใช้ได้รับอนุญาตให้เข้าถึงวัตถุที่อ้างอิง

นอกเหนือจากนั้นคุณสามารถยกประเด็นที่น่าเกลียดของสิ่งที่อาจเกิดขึ้นได้ถ้าอนุญาต

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.