SQL dinamis dalam rutinitas tersimpan MySQL

Jawaban:

8

Hanya mendengarkan pertanyaan membuat saya berpikir tentang dua aspek:

ASPEK # 1: Fungsi seharusnya DETERMINISTIK

Jika demikian, ini menyiratkan bahwa suatu fungsi harus menyajikan data pengembalian yang sama secara konsisten untuk satu set parameter tertentu, TANPA MASALAH KETIKA ANDA PANGGIL FUNGSI.

Sekarang, bayangkan fungsi yang menghasilkan jawaban yang berbeda karena mengumpulkan data pada waktu yang berbeda dalam sehari berdasarkan SQL statis dalam fungsi. Dalam arti tertentu, itu masih bisa dianggap DETERMINISTIK jika Anda meminta set tabel dan kolom yang sama setiap kali, mengingat set parameter yang sama.

Bagaimana jika Anda bisa mengubah tabel yang mendasari suatu fungsi melalui Dynamic SQL? Anda melanggar definisi fungsi DETERMINISTIK.

Perhatikan bahwa MySQL menambahkan opsi ini di /etc/my.cnf

log-bin-trust-function-creators

Meskipun ini mungkin merupakan penyederhanaan yang berlebihan untuk dikatakan, ini memungkinkan fungsi diizinkan untuk menulis data ke dalam log biner tanpa secara ketat menegakkan properti DETERMINISTIC.

ASPEK # 2: Pemicu harus dapat diputar kembali

  • Bisakah Anda membayangkan pemicu dengan semua perilaku yang sama sebagai fungsi dan kemudian memperkenalkan Dynamic SQL ke dalam campuran?
  • Bisakah Anda bayangkan mencoba menerapkan MVCC (Multiversion Concurrecy Control) terhadap Dynamic SQL setelah menerapkan MVCC ke tabel dasar pemicu itu dimaksudkan?

Anda pada dasarnya akan memiliki data yang tumbuh secara kuadratik (bahkan secara eksponensial) hanya di MVCC saja. Proses mengelola rollback SQL dengan pemicu yang bisa non-DETERMINISTIC akan menjadi rumit, untuk sedikitnya.

Mengingat kedua aspek ini, saya yakin Pengembang MySQL memikirkan hal-hal ini dan dengan cepat mengabaikannya dengan memberlakukan batasan.

Jadi, mengapa mengangkat batasan untuk Prosedur? Sederhananya, tidak ada kekhawatiran atas properti DETERMINISTIC atau Rollback.

RolandoMySQLDBA
sumber
3
Tidak dapat menjadi "rumit yang tidak bertuhan" jika DBMS lain dapat dengan baik mendukung MVCC dan SQL dinamis dalam pemicu.
a_horse_with_no_name
1
Sebenarnya, @a_horse_with_no_name, Anda benar. Untuk Oracle dan PostgreSQL, kompleks yang ilahi telah dikodekan. +1 untuk komentar Anda. MySQL memiliki keterbatasan dalam menangani beberapa mesin penyimpanan sehingga rollback dan determinisme mungkin memerlukan tumpang tindih operasi mesin penyimpanan. Itu sedikit menakutkan. Mungkin seseorang akan memiliki nyali untuk mendorong "kompleks yang tidak saleh" ke InnoDB secara penuh. Bahkan yang lebih diinginkan adalah membuat implementasi pemicu spesifik mesin penyimpanan sedemikian rupa sehingga tidak memungkinkan mesin pencampur di dalam kueri yang sama.
RolandoMySQLDBA
5

Ini pertanyaan yang bagus, tetapi saya tidak tahu jawabannya. Saya membayangkan ini harus kebagian tim internal, tetapi saya tidak tahu bahwa mereka akan menjadi besar ke situs ini. Sementara itu, saya dapat membantu Anda menyimpulkan beberapa jawaban.

Sebagai permulaan saya melihat ini:

Tembolok pemicu tidak mendeteksi kapan metadata objek yang mendasarinya telah berubah. Jika pemicu menggunakan tabel dan tabel telah berubah sejak pemicu dimuat ke dalam cache, pemicu beroperasi menggunakan metadata yang kedaluwarsa.

Yang membuat saya berpikir bahwa itu ada hubungannya dengan itu. Itu tidak akan mengkompilasi ulang SQL jika bahkan tidak memonitor metadata. Yang berarti ini masalah mesin.

Dengan cara yang sama, ketika saya membaca blok ini saya memikirkan hal yang sama (mesin):

Untuk mencegah masalah interaksi antara utas server, ketika klien mengeluarkan pernyataan, server menggunakan snapshot dari rutinitas dan pemicu yang tersedia untuk pelaksanaan pernyataan. Yaitu, server menghitung daftar prosedur, fungsi, dan pemicu yang dapat digunakan selama eksekusi pernyataan, memuatnya, dan kemudian melanjutkan untuk mengeksekusi pernyataan itu. Ini berarti bahwa sementara pernyataan dijalankan, ia tidak akan melihat perubahan pada rutinitas yang dilakukan oleh utas lainnya.

Jadi, secara keseluruhan, saya tidak sepenuhnya yakin mengapa mereka tidak mengizinkannya, tapi saya bisa menebaknya. Maaf saya tidak bisa membantu Anda lagi, saya terbuka untuk membahas ini lagi. Yang terbaik adalah berharap untuk beberapa devs MySQL yang aktif begitu kami meninggalkan beta pribadi;)

jcolebrand
sumber
1

Sebagian besar, itu karena keamanan. Pengecualian untuk prosedur adalah karena SQL dinamis dalam prosedur dapat diberikan konteks keamanan pengguna yang mengeksekusi. Ini berarti bahwa meskipun mesin tidak tahu apa yang akan dieksekusi, itu dapat memastikan bahwa pengguna diizinkan untuk mengakses objek yang dirujuk.

Di luar itu, Anda dapat mengangkat masalah buruk tentang apa yang bisa terjadi, seandainya diizinkan.

dba4life
sumber