"Jangan pernah melakukan dalam kode apa yang bisa Anda lakukan agar server SQL melakukannya dengan baik untuk Anda" - Apakah ini resep untuk desain yang buruk?

204

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.

PhonicUK
sumber
60
Ini adalah salah satu perkataan yang harus dipikirkan dengan matang. Ini dicabut setiap kali seseorang menemukan insinyur lain melakukan 'pilih * dari tabel' dan kemudian menyisir set hasil alih-alih menggunakan klausa mana dan menentukan kolom. Tetapi jika Anda mengambilnya terlalu jauh, Anda berakhir dengan kekacauan yang berbeda.
Michael Kohne
154
Memulai frase dengan "tidak pernah" atau "selalu" hampir selalu merupakan resep untuk desain yang buruk.
vsz
34
Walaupun tentu saja mungkin untuk mencoba melakukan terlalu banyak dalam SQL, saya dapat dengan jujur ​​mengatakan bahwa dalam 30 tahun pengembangan dan konsultasi, saya belum pernah melihat kasus serius yang sebenarnya (beberapa yang kecil). Di sisi lain, saya telah melihat ratusan kasus serius pengembang mencoba melakukan banyak hal dalam "kode" yang seharusnya mereka lakukan dalam SQL. Dan saya masih melihat mereka. Seringkali ...
RBarryYoung
2
@ Mr Edmundo Bawa ke meta.
ta.speot.is
4
Pertanyaan ini dua dalam satu - saya pikir itu harus dipisah. 1) Berapa banyak yang harus dilakukan dalam SQL? 2) Berapa banyak yang harus dilakukan dalam DBMS? Prosedur tersimpan berada di tengah. Saya telah melihat seluruh aplikasi dikodekan dalam prosedur tersimpan.
reinierpost

Jawaban:

321

Dalam kata-kata awam:

Ini adalah hal-hal yang dilakukan SQL untuk dilakukan dan, percaya atau tidak, saya telah melihat kode yang dilakukan:

  • bergabung - tentu saja akan membutuhkan manipulasi array yang kompleks
  • memfilter data (di mana) - secara codically itu membutuhkan memasukkan dan menghapus item dalam daftar
  • memilih kolom - tentu saja membutuhkan manipulasi daftar atau array yang berat
  • fungsi agregat - codewise itu membutuhkan array untuk menyimpan nilai dan kasus saklar yang kompleks
  • integritas kunci asing - secara codically itu akan memerlukan pertanyaan sebelum memasukkan dan mengasumsikan tidak ada yang akan menggunakan data di luar aplikasi
  • integritas kunci primer - secara codically itu akan memerlukan pertanyaan sebelum memasukkan dan mengasumsikan tidak ada yang akan menggunakan data di luar aplikasi

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.

pengguna61852
sumber
88
+10000000000 untuk menunjukkan bahwa ia menganggap semuanya berbahaya hanya akan terjadi melalui aplikasi.
HLGEM
11
@skynorth Ini mengarah ke desain database yang buruk. Bawah garis Anda berakhir dengan database yang dapat hanya dapat diakses dengan penuh arti oleh aplikasi bahwa karena semua pengolahan pasca dilakukannya.
Sirex
21
@skynorth Jika Anda mengandalkan kode untuk memastikan kunci Anda menjaga integritas, maka Anda menghapus prinsip dasar RDBMS dari DB. Itu tidak masuk akal, karena dengan demikian setiap aplikasi yang mengakses DB harus memastikan untuk secara tepat mereplikasi fungsi itu. Mengapa tidak biarkan saja DB yang menangani itu, karena memang itulah yang dirancang untuk itu. DB dapat mencegah kunci duplikat secara asli, misalnya.
Buttle Butkus
10
jangan lupa transaksi!
Sklivvz
24
@skynorth: tl; dr: Aturan yang menjaga data Anda tetap konsisten harus diimplementasikan dalam database. yaitu untuk 99% aplikasi yang pernah ditulis, data (dan karena itu database) hidup looooooooooong setelah aplikasi Anda mati dan hilang. Saya telah melihat ini berkali - kali selama bertahun-tahun (Hei, kita perlu menggunakan versi di Windows / iPhone / Android / apa pun-hal-baru-itu, karena {insert platform lama di sini} sedang sekarat, kita ' akan meng-host atau database Oracle di sini dan membuat UI baru di sana ). Tidak ada alasan untuk tren ini berhenti hari ini, atau dalam waktu dekat.
Binary Worrier
122

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 WHEREklausa, mengembalikan banyak kumpulan data lebih kecil dari pada yang lain).

Oded
sumber
27
Jika semuanya SQL akan melakukan lebih baik daripada kode aplikasi dimasukkan ke dalam lapisan SQL, ada banyak logika bisnis yang akan berakhir di database, baik atau buruk. Saya sudah melihat ini dan ya, kinerjanya sangat bagus. Tapi untungnya tim pengembang semua tahu pengembangan aplikasi dan SQL dengan sangat baik karena perbatasan antara keduanya menjadi sangat amorf. Saya tidak akan menyarankan ini sebagai titik awal melainkan titik akhir setelah sistem menjadi sangat populer dan kinerja menurun seiring waktu.
Jimmy Hoffa
3
Kuda untuk kursus init guv?
StuperUser
28
@ NathanLong Saya tidak tahu mengapa begitu banyak orang masih berpikir Anda tidak dapat menjaga SQL Anda dalam kontrol sumber. Pada awalnya kami hanya memiliki semua prosedur tersimpan kami / skrip tabel / dll yang diperlukan untuk membuat database dari awal dalam kontrol sumber, kemudian menggunakan proyek-proyek database visual studio. Itu bekerja dengan baik tanpa proyek dan lebih baik dengan mereka. SQL seperti halnya setiap hal yang dapat diubah lainnya yang diperlukan untuk membuat sistem Anda harus di bawah kendali versi! Penempatan dapat dilakukan dengan alat redgate berbeda untuk sebagian besar RDBMS jika Anda tetap membuat skrip Anda di bawah kontrol versi, jangan mempertahankan alat skrip menggunakan diff
Jimmy Hoffa
3
Jika SQL Anda memiliki dukungan untuk operasi REGEX dan manipulasi string, melakukannya dalam SQL bisa menjadi pilihan yang baik.
kevin cline
3
@ NathanLong: pikirkan seperti ini, tabel DB didefinisikan oleh sepotong kode yang ditulis dalam file teks, sintaksisnya adalah di sepanjang baris "buat tabel ...". Sekarang Anda dapat menyimpan file teks itu dalam SCM apa pun yang Anda suka, sama seperti jika Anda memiliki kode pembuatan tabel DB dalam bahasa aplikasi favorit Anda yang memanggil API apa pun yang diperlukan, dan Anda akan menyimpan file teks itu dalam SCM Anda. Saya pikir masalahnya adalah bahwa beberapa orang berpikir DB entah bagaimana binatang ajaib, dan mereka hanya tahu cara menulis kode VB (atau apa pun) dan mereka hanya berpikir dalam hal bahasa aplikasi yang mereka tahu.
gbjbaanb
47

Jangan pernah lakukan dalam kode apa yang bisa Anda lakukan agar server SQL melakukannya dengan baik untuk Anda (penekanan ada pada saya)

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:

  • Anda menyimpan tanggal lahir, dan Anda perlu menghitung usia untuk sekelompok pengguna. Anda dapat meminta SQL server melakukan pengurangan, atau Anda dapat melakukannya dalam kode Anda. Jumlah bolak-balik tetap sama, dan jumlah data yang dikirim kembali kepada Anda naik. Oleh karena itu, solusi berbasis kode menang
  • Anda menyimpan tanggal lahir, dan Anda perlu menemukan pengguna berusia antara 20 dan 30. Anda dapat memuat semua pengguna kembali pada klien, melakukan pengurangan untuk menemukan usia, dan kemudian melakukan pemfilteran, tetapi mengirimkan logika ke SQL Server akan mengurangi jumlah data tanpa memerlukan bolak-balik tambahan; Oleh karena itu, solusi berbasis SQL menang.
dasblinkenlight
sumber
1
Ketika saya bekerja di suatu tempat logika bisnis menjadi amorf dengan SQL, kami tidak mengalami masalah dengan beberapa perjalanan pulang-pergi; kami hanya menggunakan beberapa set hasil dalam satu perjalanan bolak-balik, sehingga aturan itu agak turun di sana, meskipun semangat aturan cukup bagus dalam mengincar mean emas
Jimmy Hoffa
2
+1 ini adalah jawaban yang fantastis karena memberikan contoh nyata untuk mendukung kedua arah.
Brandon
1
Pada contoh kedua Anda. apa yang Anda katakan, Jika skenarionya seperti di bawah ini - Pengguna dan bday adalah cache dan mengatakan ukuran rekaman berada dalam kisaran 1000-2000. Bukankah ini lebih cepat untuk melakukan ini dalam memori tidak ada panggilan db diperlukan karena data di-cache dan sehingga 'di antara' operasi sql dihindari. Pemrosesan akan dilakukan melalui daftar lebih dari 1000 pengguna di memori dan menemukan di mana pertandingan itu terjadi. Bukankah ini lebih cepat daripada melakukannya di db
user4677228
1
@ user4677228 Tapi coba tingkatkan :-p. Jika kode Anda harus memindai semua data untuk menghitung semua umur dan hasil yang Anda inginkan hanya "berapa banyak pengguna setidaknya 20 dan lebih muda dari 30?", Cache tidak akan membantu Anda sama sekali. Anda masih akan berakhir streaming seluruh tabel untuk klien Anda, tetapi database server bisa melakukan itu semua dalam nya memori / cache dan memberikan jawaban yang cepat terlepas dari apakah klien db menghubungkan melalui soket lokal atau jarak jauh melalui jaringan jika Anda hanya ingin menghitung usia dalam WHEREklausa.
binki
21

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.

ElYusubov
sumber
Jangan pernah meletakkan operasi yang ditetapkan dalam basis kode Anda akan berarti benar-benar semua yang dilakukan dalam LINQ untuk koleksi (pilih, jumlah, di mana, tunggal) harus dilakukan dalam SQL dan bukan di aplikasi Anda, ini akan menempatkan BANYAK logika bisnis ke dalam database Anda.
Jimmy Hoffa
4
Hal-hal yang Anda jelaskan, bukan kode klien. Ini adalah lapisan Bisnis, di mana Anda mungkin memiliki logika manipulasi Anda sendiri. Namun melakukan logika ini pada catatan 1M + akan memukul balik Anda.
EL Yusubov
@JimmyHoffa: Itu tidak benar, kadang-kadang Anda menghasilkan informasi sementara yang perlu diproses dengan data yang sudah Anda miliki di memori aplikasi. Linq melakukan keajaiban tentang hal itu.
Fabricio Araujo
@FabricioAraujo Saya menyadari mengapa LINQ bagus, tetapi jawaban ini menyatakan untuk tidak pernah melakukan operasi berbasis kode aplikasi, jika Anda tidak pernah melakukan operasi dalam kode aplikasi Anda tidak akan pernah menggunakan LINQ karena itu adalah seluruh tujuan LINQ. Saya menegaskan bahwa Jangan pernah melakukan operasi yang ditetapkan dalam kode aplikasi adalah aturan yang buruk untuk diikuti
Jimmy Hoffa
@JimmyHoffa: Tidak, aturannya mengatakan "tidak pernah melakukan apa yang RDBMS dapat lakukan untuk Anda". Dan saya berbicara tentang informasi sementara - bukan informasi yang bertahan di database. Saya bekerja pada sistem di mana, untuk memenuhi aturan bisnis, saya perlu melakukan pemrosesan kode. Saya ingat aturan bisnis yang saya miliki, setelah melakukan pemrosesan berat pada DB, melakukan pemrosesan tambahan pada data tersebut untuk menghasilkan laporan (sangat penting). Saya yang saya bisa menggunakan LINQ pada itu (itu dilakukan pada Delphi.Net sekarang-mati). Dengan kata lain, LINQ dapat digunakan bahkan mengikuti aturan itu.
Fabricio Araujo
13

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 memcachedatau 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.

tylerl
sumber
1
Uang dapat memecahkan masalah skalabilitas perangkat keras, sedangkan uang dalam jumlah tidak dapat menyelesaikan kompleksitas perangkat lunak.
Tulains Córdova
3
@ user1598390 Memang: Perangkat Keras Murah, Programmer Mahal . Uang dapat menyelesaikan kompleksitas perangkat lunak. Uang dihabiskan untuk programmer. Tetapi perhatikan bahwa kita tidak berbicara tentang kode bersih versus speghetti. Kita berbicara tentang melakukan pekerjaan di sisi aplikasi versus sisi DB. Kompleksitas perangkat lunak hanya sedikit terkait, karena kedua opsi dapat mengikuti prinsip-prinsip desain yang baik. Pertanyaan yang lebih baik adalah: " desain mana yang lebih mahal? ".
tylerl
Setelah Anda memiliki basis kode yang humongous dan penuh lemak, sebagian besar melakukan hal-hal non-bisnis, satu-satunya hal yang dapat Anda lakukan adalah ibu dari semua rekayasa ulang, yang harganya lebih dari perangkat keras dan melibatkan terlalu banyak ketidakpastian, selain itu Anda akan selalu tahu di mana menemukan perangkat keras yang bagus, tetapi programmer yang baik adalah cerita yang berbeda ... sementara pesaing Anda menggunakan waktu mereka untuk meningkatkan, beradaptasi dengan perubahan, dan membuat klien bahagia.
Tulains Córdova
1
+1 untuk menjadi satu-satunya orang yang menyebutkan penskalaan dalam jawaban Anda.
Mat
Perangkat keras itu murah, tidak lagi - di pusat data, listrik dan perangkat keras berjumlah 88% dari biaya operasional (dikutip oleh Microsoft) sehingga pengeluaran lebih banyak untuk programmer untuk menulis kode yang efisien sangat hemat biaya, dan akan sampai kita mendapatkan tanpa batas dan kekuatan fusi murah.
gbjbaanb
12

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)

HLGEM
sumber
6

"Optimalisasi prematur adalah akar dari semua kejahatan (sebagian besar, bagaimanapun) dalam pemrograman komputer" - Donald Knuth

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.

KeithS
sumber
Tunggu, tunggu, apa? Bagaimana Anda dapat dari pembuktian kebenaran hingga pengujian, yang dapat membuktikan bahwa bug ada tetapi tidak pernah dapat membuktikan bahwa kode itu benar?
Mason Wheeler
2
prosedur tersimpan bukan kode prosedural. SP adalah kueri SQL yang dihitung sebelumnya yang disimpan dan dijalankan di dalam DB. Ini bukan kode aplikasi.
gbjbaanb
1
Jika SP terbatas pada kueri SQL, maka Anda benar. Jika T-SQL atau PL / SQL termasuk istirahat bersyarat, loop, kursor dan / atau logika non-kueri lainnya, Anda salah. Dan BANYAK SP, fungsi, dan pemicu dalam DB di seluruh dunia maya memiliki elemen tambahan ini.
KeithS
5

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:

  • Ambil data ke dalam aplikasi Anda, hitung di dalam aplikasi Anda, dan kemudian kirim kembali data ke database
  • Membuat prosedur tersimpan atau serupa untuk mengambil data, menghitungnya, dan kemudian menyimpan semuanya dari satu panggilan ke SQL server.

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

Earlz
sumber
1
Anda juga lupa perjalanan jaringan - Anda tidak dapat mengukur secara horizontal dengan menambahkan server tanpa sedikit efisiensi. Jadi mengurangi beban data dengan menambahkan klausa di mana jelas - tetapi operasi sql lainnya tidak serta merta mengurangi kinerja. Poin Anda benar secara umum, tetapi tidak sampai ke titik di mana Anda memperlakukan DB sebagai datastore bodoh. Aplikasi yang paling scalable yang pernah saya kerjakan pada prosedur tersimpan yang digunakan untuk setiap panggilan data (kecuali 2 kueri kompleks). Solusi ke-3 adalah yang terbaik - "simpanan tersimpan untuk mengambil hanya data yang diperlukan", tidak yakin apakah yang Anda maksudkan sebagai 'hitung' atau tidak.
gbjbaanb
4

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.

Stanley Glass Jr
sumber
Mengapa Anda menjalankan regex atau validasi pada data yang sudah ada dalam database? Kendala harus mencegah data buruk dari tidak pernah sampai ke sana, dan penggunaan regex mungkin berarti Anda membutuhkan kolom yang lebih bermanfaat ..
Brendan Long
Saya tidak mengatakan bahwa saya akan menggunakan regex atau validasi pada data yang berasal dari database. Saya kira saya harus mengklarifikasi itu untuk data yang masuk ke database. Maksud saya di sana adalah bahwa data harus dibersihkan dan divalidasi sebelum sampai ke DAL.
Stanley Glass Jr
3

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).

mike30
sumber
mengapa downvote?
mike30
5
Saya belum downvoted, tetapi sepcialist database akan memberitahu Anda bahwa mempertimbangkan database hash bebas logika adalah ide yang sangat buruk. Ini menyebabkan masalah integritas data atau masalah kinerja atau keduanya.
HLGEM
1
@HLGEM. Jawabannya menjelaskan alasan untuk menjaga logika dalam database atau duduk di server DB. Masih belum menjelaskannya.
mike30
Mereka mungkin tidak mendapatkan ke counterpoints seperti yang saya lakukan itulah sebabnya saya tidak downvote.
HLGEM
3

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.

Chris
sumber
0

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.

Laurent Goderre
sumber
0

Ada beberapa hal yang perlu diingat:

  • Database relasional harus memastikan integritas referensial melalui kunci asing
  • Melakukan penskalaan satu basis data bisa sulit dan mahal. Melakukan penskalaan server web jauh lebih mudah hanya dengan menambahkan lebih banyak server web. Bersenang-senang mencoba menambahkan lebih banyak kekuatan SQL server.
  • Dengan C # dan LINQ, Anda dapat melakukan "bergabung" dan yang lainnya melalui kode sehingga Anda mendapatkan yang terbaik dari kedua dunia dalam banyak kasus
Joe Phillips
sumber
0

"Optimalisasi prematur adalah akar dari semua kejahatan" - Donald Knuth

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.

parasietje
sumber