Itu adalah ide yang saya dengar berulang-ulang di beberapa tempat. Beberapa lebih atau kurang mengakui bahwa sekali mencoba menyelesaikan masalah murni dalam SQL melebihi tingkat kompleksitas tertentu Anda memang harus menanganinya dalam kode.
Logika di balik idenya adalah bahwa untuk sebagian besar kasus, mesin basis data akan melakukan pekerjaan yang lebih baik dalam menemukan cara yang paling efisien untuk menyelesaikan tugas Anda daripada dalam kode. Terutama ketika hal-hal seperti membuat hasil tergantung pada operasi yang dilakukan pada data. Dapat diperdebatkan dengan mesin modern secara efektif JIT'ing + caching versi kompilasi dari kueri Anda akan masuk akal di permukaan.
Pertanyaannya adalah apakah meningkatkan mesin basis data Anda dengan cara ini secara inheren merupakan praktik desain yang buruk (dan mengapa). Garis menjadi kabur lebih lanjut ketika semua logika ada di dalam database dan Anda hanya memukulnya melalui ORM.
sumber
Jawaban:
Dalam kata-kata awam:
Ini adalah hal-hal yang dilakukan SQL untuk dilakukan dan, percaya atau tidak, saya telah melihat kode yang dilakukan:
Melakukan hal-hal ini alih-alih mengandalkan SQL atau RDBMS mengarah pada penulisan banyak kode tanpa nilai tambah , yang berarti lebih banyak kode untuk di-debug dan dipelihara. Dan itu berbahaya mengasumsikan database hanya akan diakses melalui aplikasi.
sumber
Saya akan ulangi bahwa untuk "Jangan lakukan dalam kode apa yang SQL Server dapat lakukan untuk Anda dengan baik ".
Hal-hal seperti manipulasi string, kerja regex dan semacamnya tidak akan saya lakukan di SQL Server (kecuali SQL CLR).
Di atas cenderung berbicara tentang hal-hal seperti - bergabung, mengatur operasi, dan pertanyaan. Maksud di baliknya adalah untuk mendelegasikan banyak angkat berat ke SQL Server (pada hal-hal yang baik) dan mengurangi jumlah IO sebanyak mungkin (jadi biarkan SQL melakukan penggabungan dan menyaring dengan
WHERE
klausa, mengembalikan banyak kumpulan data lebih kecil dari pada yang lain).sumber
Kunci untuk jawabannya adalah Anda perlu mencari SQL melakukan sesuatu dengan baik, bukan hanya melakukan sesuatu, untuk Anda. SQL adalah bahasa yang sangat kuat. Ditambah dengan fungsi built-in, berpotensi dapat melakukan banyak hal. Namun, fakta bahwa Anda dapat melakukan sesuatu dalam SQL seharusnya tidak menjadi alasan untuk benar-benar melakukannya dalam SQL.
Kriteria khusus saya untuk mengambil keputusan adalah melihat jumlah data yang Anda dapatkan dan jumlah perjalanan pulang-pergi: jika Anda dapat memangkas jumlah data dengan mengirimkan tugas ke server, tanpa menambah jumlah putaran- perjalanan, maka tugas berada di server; jika jumlah data tetap sama atau bertambah tanpa penurunan jumlah perjalanan bolak-balik secara simultan, tugas tersebut termasuk dalam kode Anda.
Pertimbangkan contoh-contoh ini:
sumber
WHERE
klausa.Singkatnya , akan benar untuk mengatakan bahwa: "Jangan pernah melakukan operasi khusus basis data di basis kode Anda" karena mereka lebih baik ditangani dalam basis data Anda.
Lihatlah contoh operasi basis yang ditetapkan . Seperti yang Anda ketahui, RDBMS dibuat untuk menangani operasi penyimpanan dan manipulasi data yang umum.
Selain itu, pilihan proyek database memainkan peran penting . Memiliki RDBMS (MS SQL, Oracle, dll.) Berbeda dari database NoSQL seperti RavenDB.
sumber
Sebagai aturan, DB Anda memiliki lebih banyak informasi untuk digunakan daripada aplikasi Anda, dan dapat melakukan operasi data umum dengan lebih efisien. Database Anda menyimpan indeks, misalnya, sementara aplikasi Anda harus mengindeks hasil pencarian dengan cepat. Jadi semuanya sama, beban kerja Anda secara keseluruhan dapat dikurangi dengan mendorong pekerjaan ke database daripada aplikasi.
Tetapi saat produk Anda berskala, biasanya menjadi lebih mudah untuk mengukur aplikasi Anda daripada menskalakan db Anda. Dalam instalasi besar, tidak jarang untuk melihat server aplikasi melebihi jumlah server database dengan faktor 10 hingga 1 atau lebih. Menambahkan lebih banyak server aplikasi sering kali adalah masalah sederhana mengkloning server yang ada ke perangkat keras baru. Menambahkan server database baru, di sisi lain, secara dramatis lebih sulit dalam banyak kasus.
Jadi pada titik ini, mantra menjadi melindungi basis data . Ternyata dengan menyimpan hasil basis data di dalam
memcached
atau dengan antrian pembaruan di log sisi aplikasi, atau dengan mengambil data sekali dan menghitung statistik Anda di aplikasi Anda, Anda dapat secara dramatis mengurangi beban kerja database Anda, menyelamatkan Anda dari keharusan untuk menggunakan konfigurasi DB cluster yang lebih rumit dan rapuh.sumber
Saya pikir itu akan menjadi desain yang buruk untuk tidak menggunakan database untuk hal-hal yang dimaksudkan. Saya belum pernah melihat basis data mana pun yang menerapkan aturan di luar basis data yang memiliki data yang baik. Dan saya telah melihat ratusan basis data.
Jadi hal-hal yang harus dilakukan dalam database:
Pengauditan (audit hanya aplikasi tidak akan melacak semua perubahan pada basis data dan karenanya tidak berharga).
Kendala ingerity data termasuk nilai default, batasan kunci asing dan aturan yang harus selalu diterapkan pada semua data. Semua data tidak selalu diubah atau dimasukkan melalui aplikasi, ada perbaikan data satu kali terutama dari kumpulan data besar yang tidak praktis untuk melakukan satu catatan pada satu waktu (perbarui 100.000 catatan ini yang mendapat ketidakcocokan sebagai status 1 saat mereka seharusnya menjadi 2 karena bug kode aplikasi atau perbarui semua catatan dari klien A ke klien B karena perusahaan B membeli perusahaan A) dan impor data dan aplikasi lain yang mungkin menyentuh database yang sama.
GABUNG dan di mana penyaringan klausa (untuk mengurangi jumlah catatan yang dikirim di seluruh jaringan)
sumber
Basis datanya persis seperti itu; lapisan data aplikasi Anda. Tugasnya adalah menyediakan aplikasi Anda dengan data yang diminta, dan menyimpan data yang diberikan kepadanya. Aplikasi Anda adalah tempat untuk meletakkan kode yang benar-benar berfungsi dengan data; menampilkannya, memvalidasinya, dll.
Sementara sentimen dalam baris judul sangat mengagumkan, dan akurat sampai titik tertentu (seluk-beluk penyaringan, proyeksi, pengelompokan dll harus dalam jumlah besar kasus diserahkan kepada DB), definisi "baik" mungkin di memesan. Banyak tugas yang bisa dijalankan oleh SQL Server dengan tingkat kinerja tinggi, tetapi tugas yang bisa Anda contohkanSQL Server melakukannya dengan benar dengan cara yang terisolasi dan berulang sangat sedikit. SQL Management Studio adalah IDE basis data yang hebat (terutama mengingat opsi lain yang pernah saya gunakan seperti TOAD), tetapi ia memiliki keterbatasan, pertama di antaranya adalah hampir semua yang Anda gunakan (atau kode prosedural yang Anda jalankan di DB di bawahnya) secara definisi merupakan "efek samping" (mengubah keadaan yang berada di luar domain ruang memori proses Anda). Selain itu, kode prosedural dalam SQL Server baru saja, dengan IDE dan alat terbaru, dapat diukur cara kode dikelola dapat menggunakan metrik cakupan dan analisis jalur (sehingga Anda dapat menunjukkan bahwa pernyataan khusus ini jika ditemui oleh tes X , Y, dan Z, dan uji X dirancang untuk membuat kondisi benar dan jalankan setengahnya sementara Y dan Z mengeksekusi "lain" . Itu, pada gilirannya, mengasumsikan Anda memiliki tes yang dapat mengatur database dengan keadaan awal tertentu, menjalankan kode prosedural database melalui beberapa tindakan, dan menegaskan hasil yang diharapkan.
Semua ini jauh lebih sulit dan terlibat daripada solusi yang disediakan oleh sebagian besar lapisan akses data; menganggap layer data (dan, dalam hal ini, DAL) tahu bagaimana melakukan pekerjaan mereka ketika diberi input yang benar, dan kemudian menguji bahwa kode Anda memberikan input yang benar. Dengan menjaga kode prosedural seperti SP dan memicu keluar dari DB dan bukannya melakukan hal-hal semacam itu dalam kode aplikasi, kata kode aplikasi lebih mudah untuk dilakukan.
sumber
Salah satu hal yang tampaknya tidak disadari orang adalah melakukan semua pemrosesan Anda pada SQL server tidak selalu baik, terlepas dari pengaruhnya pada kualitas kode.
Misalnya, jika Anda perlu mengambil beberapa data dan kemudian menghitung sesuatu dari data dan kemudian menyimpan data itu dalam database. Ada dua pilihan:
Anda mungkin berpikir bahwa solusi kedua selalu yang tercepat, tetapi ini jelas tidak benar. Saya mengabaikan bahkan jika SQL cocok untuk masalah (yaitu regex dan manipulasi string). Mari kita berpura-pura memiliki SQL CLR atau sesuatu yang mirip dengan memiliki bahasa yang kuat dalam database bahkan. Jika diperlukan 1 detik untuk melakukan perjalanan pulang pergi dan mendapatkan data dan 1 detik untuk menyimpannya, lalu 10 detik untuk melakukan perhitungan melintasinya. Anda melakukan kesalahan jika Anda melakukan semuanya dalam database.
Tentu, Anda mencukur 2 detik. Namun, apakah Anda lebih suka membuang 100% (setidaknya) satu inti CPU pada server database Anda selama 10 detik, atau apakah Anda lebih suka membuang waktu itu di server web Anda?
Server web mudah ditingkatkan, database di sisi lain sangat mahal, terutama database SQL. Sebagian besar waktu, server web "stateless" juga dan dapat ditambahkan dan dihapus sesuka hati tanpa konfigurasi tambahan untuk apa pun kecuali penyeimbang beban.
Jadi, pikirkan bukan hanya tentang mencukur 2 detik dari operasi, tetapi juga memikirkan skalabilitas. Mengapa membuang sumber daya yang mahal seperti sumber daya server database ketika Anda dapat menggunakan sumber daya server web yang jauh lebih murah dengan dampak kinerja yang relatif kecil
sumber
Saya suka melihatnya sebagai SQL hanya harus berurusan dengan data itu sendiri. Aturan bisnis yang memutuskan seperti apa kueri itu bisa terjadi dalam kode. Regex atau validasi informasi harus dilakukan dalam kode. SQL harus dibiarkan bergabung dengan tabel Anda, kueri data Anda, masukkan data bersih, dll.
Apa yang diteruskan ke SQL harus berupa data bersih dan SQL seharusnya tidak benar-benar perlu tahu apa pun lebih dari yang diperlukan untuk menyimpannya, memperbarui, menghapusnya atau mengambil sesuatu. Saya telah melihat terlalu banyak pengembang yang ingin membuang logika bisnis dan pengkodean dalam SQL karena mereka menganggap data sebagai bisnis mereka. Pisahkan logika Anda dari data Anda dan Anda akan menemukan kode Anda menjadi lebih bersih dan lebih mudah dikelola.
Hanya $ 0,02 saya.
sumber
Secara umum saya setuju bahwa kode harus mengontrol logika bisnis dan DB harus menjadi hash bebas logika. Tapi di sini ada beberapa poin balasan:
Batasan primer, kunci asing, dan yang diperlukan (bukan nol) dapat ditegakkan dengan kode. Kendala adalah logika bisnis. Haruskah mereka dikeluarkan dari database karena mereka menduplikasi kode apa yang bisa dilakukan?
Apakah pihak lain di luar kendali Anda menyentuh database? Jika demikian memiliki kendala yang diberlakukan dekat dengan data itu bagus. Akses dapat dibatasi untuk layanan web yang menerapkan logika, tetapi ini mengasumsikan Anda ada "pertama" dan memiliki kekuatan untuk menegakkan penggunaan layanan pada pihak lain.
Apakah ORM Anda melakukan penyisipan / pembaruan terpisah untuk setiap objek? Jika ya, maka Anda akan memiliki masalah kinerja yang parah saat memproses kumpulan data dalam jumlah besar. Mengatur operasi adalah cara untuk pergi. ORM akan mengalami kesulitan memodelkan secara akurat semua set yang mungkin bergabung tempat Anda dapat melakukan operasi.
Apakah Anda menganggap "lapisan" sebagai pemisahan fisik oleh server, atau pemisahan logis? Menjalankan logika di server mana pun secara teoritis masih bisa berada di bawah lapisan logisnya. Anda dapat mengatur pemisahan dengan mengkompilasi ke server DLL yang berbeda daripada membelah secara eksklusif. Ini secara dramatis dapat meningkatkan waktu respons (tetapi mengorbankan througput) sambil mempertahankan pemisahan masalah. DLL split nantinya dapat dipindahkan ke server lain tanpa build baru untuk meningkatkan throughput (dengan biaya waktu respons).
sumber
Ungkapan ini lebih berkaitan dengan menjaga aturan bisnis, hubungannya dengan data, bersama dengan hubungan (data dan struktur dan hubungan.) Ini bukan one-stop-shop untuk setiap masalah tetapi membantu menghindari hal-hal seperti secara manual mempertahankan catatan penghitung, menjaga hubungan integritas dll, jika hal-hal ini tersedia di tingkat database Jadi jika orang lain datang dan memperluas program atau menulis program lain yang berinteraksi dengan database, mereka tidak perlu mencari cara untuk menjaga integritas database dari kode sebelumnya. Kasus penghitung catatan yang dikelola secara manual sangat relevan ketika orang lain ingin membuat program baru untuk berinteraksi dengan database yang sama. Bahkan jika program yang baru dibuat memiliki kode yang tepat untuk penghitung, program asli dan yang baru berjalan pada waktu yang hampir bersamaan kemungkinan akan merusaknya. Bahkan ada kode di luar sana yang mengambil catatan dan memeriksa kondisi sebelum menulis catatan baru atau yang diperbarui (dalam kode atau sebagai permintaan terpisah), ketika jika memungkinkan hal ini sering dapat dicapai tepat di menyisipkan atau memperbarui pernyataan. Korupsi data dapat kembali terjadi. Mesin basis data menjamin keaslian; pembaruan atau masukkan kueri dengan ketentuan dijamin hanya akan memengaruhi catatan yang memenuhi persyaratan dan tidak ada kueri eksternal yang dapat mengubah data setengah jalan melalui pembaruan kami. Ada banyak keadaan lain di mana kode digunakan ketika mesin database lebih baik melayani. Ini semua tentang integritas data dan bukan tentang kinerja. bahkan kode di luar sana yang mengambil catatan dan memeriksa kondisi sebelum menulis catatan baru atau yang diperbarui (dalam kode atau sebagai permintaan terpisah), ketika jika memungkinkan hal ini sering dapat dicapai tepat di masukkan atau perbarui pernyataan. Korupsi data dapat kembali terjadi. Mesin basis data menjamin keaslian; pembaruan atau masukkan kueri dengan ketentuan dijamin hanya akan memengaruhi catatan yang memenuhi persyaratan dan tidak ada kueri eksternal yang dapat mengubah data setengah jalan melalui pembaruan kami. Ada banyak keadaan lain di mana kode digunakan ketika mesin database lebih baik melayani. Ini semua tentang integritas data dan bukan tentang kinerja. bahkan kode di luar sana yang mengambil catatan dan memeriksa kondisi sebelum menulis catatan baru atau yang diperbarui (dalam kode atau sebagai permintaan terpisah), ketika jika memungkinkan hal ini sering dapat dicapai tepat di masukkan atau perbarui pernyataan. Korupsi data dapat kembali terjadi. Mesin basis data menjamin keaslian; pembaruan atau masukkan kueri dengan ketentuan dijamin hanya akan memengaruhi catatan yang memenuhi persyaratan dan tidak ada kueri eksternal yang dapat mengubah data setengah jalan melalui pembaruan kami. Ada banyak keadaan lain di mana kode digunakan ketika mesin database lebih baik melayani. Ini semua tentang integritas data dan bukan tentang kinerja. Mesin basis data menjamin keaslian; pembaruan atau masukkan kueri dengan ketentuan dijamin hanya akan memengaruhi catatan yang memenuhi persyaratan dan tidak ada kueri eksternal yang dapat mengubah data setengah jalan melalui pembaruan kami. Ada banyak keadaan lain di mana kode digunakan ketika mesin database lebih baik melayani. Ini semua tentang integritas data dan bukan tentang kinerja. Mesin basis data menjamin keaslian; pembaruan atau masukkan kueri dengan ketentuan dijamin hanya akan memengaruhi catatan yang memenuhi persyaratan dan tidak ada kueri eksternal yang dapat mengubah data setengah jalan melalui pembaruan kami. Ada banyak keadaan lain di mana kode digunakan ketika mesin database lebih baik melayani. Ini semua tentang integritas data dan bukan tentang kinerja.
Jadi itu sebenarnya idiom desain yang bagus atau aturan praktis. Tidak ada jumlah kinerja yang akan membantu dalam sistem dengan data yang rusak.
sumber
Seperti disebutkan sebelumnya, tujuannya adalah mengirim dan menerima sesedikit mungkin dari basis data karena perjalanan pulang pergi sangat memakan waktu. Mengirim statemen SQL berulang-ulang adalah buang-buang waktu terutama dalam pertanyaan yang lebih kompleks.
Menggunakan prosedur tersimpan dalam database memungkinkan pengembang untuk berinteraksi dengan database seperti API, tanpa khawatir tentang skema kompleks di bagian belakang. Ini juga mengurangi data yang dikirim ke server karena hanya nama dan beberapa parameter yang dikirim. Dalam skenario ini, sebagian besar logika bisnis masih bisa dalam kode tetapi tidak dalam bentuk SQL. Kode dasarnya akan mempersiapkan apa yang akan dikirim atau diminta dari database.
sumber
Ada beberapa hal yang perlu diingat:
sumber
Gunakan alat yang paling tepat untuk pekerjaan itu. Untuk integritas data, ini sering merupakan basis data. Untuk aturan bisnis tingkat lanjut, ini adalah sistem berbasis aturan seperti JBoss Drools. Untuk visualisasi data, ini akan menjadi kerangka pelaporan. dll.
Jika Anda memiliki masalah kinerja, Anda kemudian harus melihat apakah data dapat di-cache, atau apakah implementasi dalam database akan lebih cepat. Secara umum, biaya untuk membeli server tambahan atau daya cloud ekstra akan jauh lebih rendah daripada biaya pemeliharaan tambahan dan dampak bug tambahan.
sumber