Apakah saya benar-benar membutuhkan pemicu untuk basis data relasional, misalnya, PostgreSQL?

10

Saya tahu bahwa pemicu dapat digunakan untuk memvalidasi data yang disimpan agar database tetap konsisten. Namun, mengapa tidak melakukan validasi data di sisi aplikasi sebelum menyimpannya ke dalam database?

Misalnya, kami menyimpan klien, dan kami ingin melakukan beberapa validasi yang tidak dapat dengan mudah dilakukan pada level DDL. https://severalnines.com/blog/postgresql-triggers-and-stored-function-basics

Contoh lain adalah audit.

Memperbarui

Bagaimana pemicu dan transaksi basis data bekerja bersama. Misalnya, jika saya ingin melakukan validasi data yang dimasukkan. Ini dilakukan di dalam suatu transaksi. Apa yang terjadi sebelumnya: transaksi dilakukan atau pemicu dieksekusi?

Yan Khonski
sumber
However, why not perform validation of data on the application side before storing them into the database?nah, keduanya tidak saling eksklusif. Kemungkinan Anda akan memvalidasi hal-hal yang berbeda di kedua sisi. Sementara validasi di sisi aplikasi adalah bisnis-sentris, validasi pada database lebih banyak data-sentris. Pikirkan dalam basis data yang diumpankan oleh beberapa aplikasi dan berbeda.
Laiv
Apakah Anda perlu memasukkan data dari sumber luar yang hanya melakukan dump data tanpa berpikir ke dalam sistem Anda? Jika demikian, Anda mungkin memiliki kasus di mana Anda perlu memasukkan data dalam format yang tidak valid untuk koreksi nanti. Dalam hal ini, pemicu akan menyebabkan masalah tanpa akhir. Ingatlah ini. Terkadang Anda tidak ingin pemicu dieksekusi.
Greg Burghardt
Pembaruan Anda harus berupa pertanyaan sendiri, mungkin pada SO, tetapi pertanyaan Anda sudah memiliki jawaban tentang Database Administrators.SE . Singkatnya, bahkan pemicu "setelah pembaruan" dijalankan sebelum transaksi dilakukan, dan jika pengecualian dilemparkan ke dalam pemicu, itu akan menyebabkan kemunduran.
Doc Brown
@GregBurghardt Sebagian besar database memiliki pernyataan yang dapat digunakan untuk menonaktifkan pemicu untuk jenis aktivitas tersebut.
Blrfl
1
@ Blrfl: Ya, tetapi Anda harus menyadari bahwa pemicu tersebut dapat dinonaktifkan sementara untuk semua pengguna yang terhubung, ketika Anda hanya ingin menonaktifkan cek tersebut untuk sesi saat ini.
Greg Burghardt

Jawaban:

12

Tergantung pada jenis sistem aplikasi yang Anda bangun:

  • jika Anda membuat sistem aplikasi-sentris yang hanya berisi satu aplikasi utama, dengan basis data khusus untuk aplikasi ini, dan idealnya satu tim yang bertanggung jawab untuk mengembangkan aplikasi dan basis data berdampingan, Anda dapat menyimpan semua logika validasi dan juga mengaudit logika di dalam aplikasi.

    Manfaat utama dari hal ini adalah Anda tidak harus mendistribusikan logika bisnis antara aplikasi dan db, sehingga memelihara dan mengembangkan sistem menjadi lebih mudah. Sebagai bonus, Anda tidak mengikat aplikasi terlalu banyak ke tipe DBMS atau vendor DBMS tertentu. Pendekatan ini jelas diperlukan jika aplikasi Anda ingin dapat menggunakan sistem DB ringan yang tidak menyediakan pemicu.

  • Namun, jika Anda membuat sistem di mana banyak aplikasi yang berbeda berbagi basis data yang sama, dan itu tidak dapat membayangkan sebelumnya aplikasi mana yang akan menuliskannya di masa depan, atau tim mana yang akan mengembangkan aplikasi untuk mengisi data ke db di masa depan, maka itu akan lebih baik database Anda akan bertanggung jawab untuk menjamin konsistensi data sebanyak mungkin. Dan di situlah pemicu menjadi sangat membantu. Dalam sistem yang lebih besar, kendala referensial seringkali tidak cukup untuk ini, tetapi pemicu yang menyebut prosedur tersimpan dapat menerapkan hampir semua jenis validasi yang Anda butuhkan.

Alasan lain untuk menggunakan pemicu adalah kinerja: dalam model data yang kompleks, tidak jarang dijumpai aturan konsistensi kompleks yang mengharuskan untuk menggunakan banyak data tambahan yang bukan bagian dari rangkaian kerja saat ini yang tersedia di aplikasi klien. Mentransfer semua data tersebut melalui jaringan terlebih dahulu untuk memungkinkan validasi di sisi klien dapat memiliki dampak kinerja yang penting.

Lihat juga posting SE yang lebih tua ini: Logika Aplikasi Vs DB Pemicu untuk pembersihan basis data

Jadi putuskan sendiri sistem seperti apa yang Anda bangun, maka Anda dapat membuat keputusan yang sudah ada apakah pemicu adalah alat yang tepat untuk kasus Anda atau tidak.

Doc Brown
sumber
3

Saya pikir pertanyaannya adalah tentang tanggung jawab atas kualitas data.

Jawabannya tergantung pada bagaimana Anda melihat sistem.

Jika Anda melihat database sebagai layanan independen, berbeda, dan otonom terpisah dari aplikasi, maka database bertanggung jawab untuk memastikan konsistensi dan kualitas data yang dikandungnya. Pada dasarnya karena database tersebut dapat digunakan oleh aplikasi yang berbeda, sehingga tidak dapat bergantung pada aplikasi kedua yang memiliki perilaku dan kualitas yang sama. Dalam keadaan ini, basis data perlu dirancang untuk mengekspos API dan perilaku otonom. Dalam pandangan ini setidaknya ada dua aplikasi, salah satunya adalah database dan yang lainnya adalah aplikasi yang menggunakannya.

Sebaliknya, basis data dapat dianggap sebagai bentuk file yang rumit yang berada di bawah kendali langsung dan total aplikasi. Dalam hal ini database berubah menjadi serialisasi murni dan alat navigasi dokumen. Ini mungkin menyediakan beberapa perilaku lanjut untuk mendukung permintaan, dan pemeliharaan dokumen (seperti JSON, atau alat XML lakukan) tetapi sekali lagi tidak harus (seperti kebanyakan aliran file lakukan). Dalam hal ini murni tanggung jawab program untuk mempertahankan format dan konten yang benar dalam file. Dalam tampilan ini ada satu aplikasi.

Dalam kedua tampilan, pertanyaan selanjutnya adalah bagaimana mendukung penggunaan database sebagai file mewah, atau layanan terpisah. Anda dapat mencapai ini dengan:

  • menggunakan alat-alat yang disediakan platform database dalam bentuk tabel / tampilan / prosedur tersimpan / pemicu / dll ...
  • membungkus basis data itu sendiri dalam suatu layanan yang harus digunakan semua klien untuk mengakses basis data
  • membungkus basis data di perpustakaan yang harus digunakan oleh semua klien untuk mengakses data.

Masing-masing dilengkapi dengan pro / kontra sendiri dan akan bergantung pada kendala arsitektur lingkungan di mana sistem beroperasi.

Apa pun tampilan yang Anda ambil, selalu terbayar untuk memvalidasi data pada batas.

  • Validasikan bidang pada UI yang dimasukkan pengguna
  • Validasi permintaan jaringan / API sebelum meninggalkan klien
  • Validasi permintaan jaringan / API di server sebelum melakukan apa pun
  • Validasi data yang dimasukkan ke dalam aturan bisnis
  • Validasikan data sebelum bertahan
  • Validasikan data setelah diambil dari ketekunan
  • seterusnya dan seterusnya

Berapa banyak validasi dijamin pada setiap batas tergantung pada seberapa berisiko itu untuk tidak memvalidasinya.

  • mengalikan dua angka bersamaan?
    • Anda mendapatkan nomor yang salah apakah itu masalah?
  • menjalankan prosedur pada lokasi memori yang diberikan?
    • Apa yang ada di lokasi memori itu?
    • Apa yang terjadi jika objek tidak ada, atau dalam kondisi buruk?
  • menggunakan regex pada string yang berisi kanji?
    • Bisakah modul regex menangani unicode?
    • Bisakah regex menangani unicode?
Kain0_0
sumber
Logika validasi sentralisasi bagus, tetapi pemicu imho bukan cara yang baik untuk mengimplementasikannya. Saya dulu bekerja pada sistem di mana beberapa aplikasi semua berbagi database, dengan semua logika validasi dan efek samping diimplementasikan dalam database melalui pemicu dan prosedur tersimpan. Saya datang dengan kesan bahwa lebih baik memiliki layanan Microsoft di depan database dan mengimplementasikan semua logika di sana. Logika non-sepele dalam database SQL adalah anti-pola.
Joeri Sebrechts
1
@ JoeriSebrechts Oke, saya akan gigit: mengapa logika nontrivial dalam database adalah antipattern, dan apa yang membuatnya lebih sebagai antipattern daripada memasukkannya ke dalam program yang dikelola secara terpisah?
Blrfl
@ Bllfl Dua alasan, API untuk mengakses logika di DB lebih rendah daripada API layanan web (lebih sulit untuk versi, lebih sulit untuk digunakan, tidak mudah di-cache, ...), dan basis data membuatnya lebih sulit untuk secara rapi menyusun dan memelihara basis kode di-host di dalamnya. Dalam pengalaman saya, lebih mudah untuk meng-host logika di layanan web di depan database daripada di dalam database itu.
Joeri Sebrechts
@ JoeriSebrechts Saya setuju bahwa sebagian besar platform Database menyediakan alat yang menyedihkan untuk mengimplementasikan API yang kredibel, bermanfaat, dan dapat dikembangkan. Dalam banyak hal itu tentu saja merupakan undangan untuk merasakan banyak kesakitan. Maksud saya adalah ini tentang perspektif, menyadari bahwa DB adalah file mewah, atau bahwa itu benar-benar layanan terpisah mengarah ke pertanyaan berikutnya yaitu bagaimana membungkusnya untuk mendukung gaya penggunaan itu. Saya akan menguraikan jawaban saya untuk memperjelasnya.
Kain0_0
2

Tidak, Anda tidak boleh menggunakan pemicu untuk melakukan validasi.

Basis data hanya bertanggung jawab atas integritasnya sendiri. Setiap pengguna yang menghadapi validasi harus dilakukan oleh aplikasi Anda.

Database melakukan tiga level validasi untuk integritas. Yang pertama adalah validasi tingkat bidang. Suatu bidang dapat diminta, jika tidak ada nilai (nol) itu adalah kesalahan. Ini juga bisa menjadi kendala pemeriksaan; suatu domain memiliki jumlah nilai yang disebutkan.

Kedua ada hubungan antar tabel. Dalam satu tabel Anda menyimpan satu atau beberapa kunci asing, menghubungkan tabel ini ke tabel lain dan membutuhkan nilai-nilai untuk menjadi kunci yang valid untuk "tabel lain". Pikirkan basis data alamat, tempat kami mendukung alamat berbagai negara. Kunci negara dalam suatu alamat harus menunjuk ke negara yang dikenal. Apakah data (misalnya kode pos) valid, bukan masalah pemeriksaan integritas ini.

Ketiga dan paling rumit adalah pemicu. Sebagai aturan umum ini harus membahas (pun tidak dimaksudkan) menyangkut aturan integritas yang bersyarat. Untuk kembali ke contoh alamat: jika suatu negara tidak memiliki kode pos, itu akan menjadi masalah jika suatu negara dalam daftar ini akan memiliki kode pos. Jadi ceknya adalah: jika negara ini tidak memiliki kode pos, bidang kode pos harus nol.

Validasi adalah masalah aplikasi. Fakta bahwa kode pos Jerman hanya terdiri dari digit adalah pemeriksaan yang harus dilakukan aplikasi, bukan database. Garisnya tipis, jadi Anda mungkin perlu berpikir / berdiskusi dalam beberapa kasus jika ada sesuatu yang menjadi pemicu (melindungi integritas basis data Anda) atau dalam aplikasi (pengguna menghadapi validasi).

Menno Hölscher
sumber
Hanya ingin menambahkan bahwa jika OP perlu menambahkan aturan validasi acomplex yang perlu ada dalam database ia selalu dapat menggunakan prosedur tersimpan sebagai alternatif yang lebih aman.
Borjab
@ Borjab: Validasi seperti menjaga database tetap benar, mungkin. Tetapi pengguna menghadapi validasi? Tidak.
Menno Hölscher
1
Pernyataan pertama Anda mengatakan "jangan pernah menggunakan pemicu untuk melakukan validasi" , tetapi di bawah Anda menulis, "ya, Anda bisa menggunakan pemicu untuk jenis validasi tertentu, dan tidak jelas secara inheren di mana harus menggambar garis". Ini berbunyi sangat kontradiktif. Saya akan merekomendasikan untuk menghapus kalimat pertama Anda, yang akan sangat meningkatkan jawaban Anda. Oh, dan kalimat terakhir Anda tidak menjawab pertanyaan pembaruan OP, karena "sebelum / sesudah" tidak ada hubungannya dengan transaksi. Saya akan merekomendasikan untuk menghapusnya juga. (lihat komentar saya di bawah pertanyaan OP).
Doc Brown
@DocBrown Perbedaannya adalah antara melindungi database dari korupsi dan validasi yang dihadapi pengguna. Jadi dalam "validasi lebih lanjut" saya merujuk ke pengguna yang menghadapi validasi. Bagaimana saya bisa membuat perbedaan ini lebih jelas? Sebagai permulaan saya menghapus "lanjut".
Menno Hölscher
2
Tidak apa-apa untuk melakukan validasi dalam database. Sama seperti itu baik-baik saja untuk melakukannya dalam aplikasi. Keduanya memiliki kelebihan. Melakukan validasi Anda dalam aplikasi berarti Anda harus sangat berhati-hati setiap kali Anda menjalankan SQL tanpa ORM Anda yang diperlukan untuk hampir semua aplikasi yang kompleks.
Qwertie
1

Audit adalah contoh klasik dari penggunaan pemicu secara efektif. Saya telah menemukan beberapa kesalahan yang dilakukan oleh tester (memindahkan klien dari satu tingkat layanan ke yang lain) berkat tabel Audit yang diterapkan oleh pemicu. Saya sangat merekomendasikan menggunakan pemicu untuk audit.

Validasi dapat dilakukan di tingkat ujung depan, tetapi saya telah melihat kesalahan aneh dalam database yang telah saya tangani (orang yang lahir pada tahun 3000, dll), dan karena beberapa dari mereka membuat sendiri, saya sangat merekomendasikan memiliki lapisan tambahan validasi dalam database, untuk berjaga-jaga. Tentu saja, jenis kesalahan tersebut dapat dihindari dengan kendala pemeriksaan, dan sering kali mereka lebih efektif (dalam MS SQL mereka adalah metode yang disukai; selalu periksa dokumentasi).

Hila DG
sumber
1

Karena pertanyaannya adalah apakah kita benar-benar membutuhkan pemicu untuk basis data relasional di sini adalah beberapa kasus penggunaan lainnya tempat menggunakan pemicu:

  1. Untuk audit seperti dijelaskan dalam jawaban lain.
  2. Mengaudit dalam arti yang lebih luas: jika entri basis data diubah, pemicu dapat merekam acara untuk pemrosesan posting asychroneous, misalnya ekspor malam ke aplikasi lain.
  3. Pemicu untuk dilihat: pemicu dapat ditentukan instead of. Dengan cara ini orang dapat menyisipkan, memperbarui, dan menghapus entri dari tampilan. Pemicu dapat menyebarkan tindakan ini ke beberapa tabel. Ini adalah cara untuk membuat tampilan terbatas tersedia tanpa memaparkan detail tabel yang mendasarinya.
  4. Untuk secara eksplisit menyimpan perputaran basis data: asumsikan hubungan N: M antara tabel A dan B dan tabel perantara R. Anda dapat mendefinisikan batasan kunci asing dari R ke A serta B yang menetapkan bahwa entri dalam R akan dihapus jika entri yang sesuai di B dihapus. Namun, logika bisnis terkadang mensyaratkan bahwa entri di A harus memiliki setidaknya satu hubungan dengan entri di B. Dalam hal ini pemicu penghapusan R dapat membantu untuk menegakkan logika ini: jika untuk entri di A entri terakhir di R dihapus maka pemicu dapat menghapus A. Dalam tampilan sentris aplikasi setidaknya diperlukan dua putaran. Ini adalah contoh untuk validasi. Contoh lain dapat dipahami: di samping kasus penggunaan (1), (2),
  5. Percaya: terkadang admin database mengubah entri pada baris perintah tidak menggunakan aplikasi Anda. Admin bekerja dengan hati-hati dan tahu apa yang mereka lakukan. Namun, terkadang mereka mungkin salah. Jika konsistensi sangat penting pemicu adalah sabuk pengaman mereka.

Sebagai kelemahan logika bisnis didistribusikan antara lapisan-lapisan dan ini merupakan kerugian utama untuk pemeliharaan. Seperti penulis lain menulis, itu adalah batas tipis antara aplikasi dan database dan pilihannya tidak selalu jelas. Pendapat pribadi saya adalah pemicu yang menempatkan beban pada pengembang. Mereka dapat menghemat waktu dalam pengembangan. Jelas mereka meningkatkan pengalaman pengguna karena mereka meningkatkan kinerja melalui koneksi jaringan yang lambat.

Claude
sumber