Saya telah bekerja di beberapa proyek di mana sebagian besar logika bisnis diterapkan pada database (kebanyakan melalui prosedur tersimpan). Di sisi lain, saya pernah mendengar dari beberapa rekan programmer bahwa ini adalah praktik yang buruk ("Database ada untuk menyimpan data. Aplikasi ada di sana untuk melakukan sisanya").
Manakah dari pendekatan ini yang umumnya lebih baik?
Kelebihan menerapkan logika bisnis dalam DB yang dapat saya pikirkan adalah:
- Sentralisasi logika bisnis;
- Independensi tipe aplikasi, bahasa pemrograman, OS, dll;
- Database kurang rentan terhadap migrasi teknologi atau refactoring besar (AFAIK);
- Tidak ada pengerjaan ulang migrasi teknologi aplikasi (mis: .NET ke Java, Perl ke Python, dll).
Kontra:
- SQL kurang produktif dan lebih kompleks untuk pemrograman logika bisnis, karena kurangnya perpustakaan dan konstruksi bahasa yang ditawarkan oleh kebanyakan bahasa yang berorientasi aplikasi;
- Kode yang lebih sulit (jika mungkin sama sekali) digunakan kembali melalui perpustakaan;
- IDE kurang produktif.
Catatan: Basis data yang saya bicarakan adalah basis data relasional, basis data populer seperti SQL Server, Oracle, MySql dll.
Terima kasih!
Jawaban:
Logika bisnis tidak masuk ke dalam basis data
Jika kita berbicara tentang aplikasi multi-tier, tampaknya cukup jelas bahwa logika bisnis, jenis kecerdasan yang menjalankan perusahaan tertentu, termasuk dalam Lapisan Logika Bisnis, bukan dalam Lapisan Akses Data.
Database melakukan beberapa hal dengan sangat baik:
Sekarang, tentu saja, Anda dapat menyusun semua hal dalam basis data yang berkaitan dengan masalah bisnis Anda, hal-hal seperti tarif pajak, diskon, kode operasi, kategori, dan sebagainya. Tetapi tindakan bisnis yang diambil pada data tersebut umumnya tidak dikodekan ke dalam basis data, karena segala macam alasan yang telah disebutkan oleh orang lain, meskipun suatu tindakan dapat dipilih dalam basis data dan dieksekusi di tempat lain.
Dan tentu saja, mungkin ada hal-hal yang dilakukan dalam database untuk kinerja dan alasan lain:
Secara alami, tidak ada yang terukir di batu. Stored Prosedur cocok untuk beragam tugas hanya karena mereka tinggal di server database dan memiliki kekuatan dan kelebihan tertentu.
Prosedur Tersimpan Di Mana Saja
Ada daya pikat tertentu untuk mengode semua tugas penyimpanan, pengelolaan, dan pengambilan data dalam prosedur tersimpan, dan hanya mengonsumsi layanan data yang dihasilkan. Anda tentu akan mendapat manfaat dari optimalisasi kinerja dan keamanan semaksimal mungkin yang disediakan oleh server database, dan itu bukan hal kecil.
Tapi apa risikonya?
Dan tentu saja, jika Anda memerlukan layanan web (yang mungkin merupakan tujuan semua ini), Anda masih harus membangunnya.
Jadi apa praktik yang khas?
Saya akan mengatakan bahwa pendekatan modern yang khas adalah menggunakan Object-Relational Mapper (seperti Entity Framework) untuk membuat kelas yang memodelkan tabel Anda. Anda kemudian dapat berbicara ke database Anda melalui repositori yang mengembalikan koleksi objek, situasi yang sangat akrab bagi pengembang perangkat lunak yang kompeten. ORM secara dinamis menghasilkan SQL yang sesuai dengan model data Anda dan informasi yang diminta, yang kemudian diproses oleh server database untuk mengembalikan hasil kueri.
Seberapa baik ini bekerja? Sangat bagus, dan jauh lebih cepat daripada menulis prosedur dan pandangan yang tersimpan. Ini biasanya mencakup sekitar 80% dari persyaratan akses data Anda, kebanyakan CRUD. Apa yang mencakup 20% lainnya? Anda dapat menebaknya: prosedur tersimpan, yang didukung langsung oleh semua ORM utama.
Bisakah Anda menulis pembuat kode yang melakukan hal yang sama dengan ORM, tetapi dengan prosedur tersimpan? Tentu kamu bisa. Tapi ORM umumnya vendor-independen, dipahami dengan baik oleh semua orang, dan lebih didukung.
sumber
Saya sangat percaya dalam menjaga logika bisnis dari database sebanyak mungkin. Namun, sebagai pengembang kinerja perusahaan saya, saya menghargai bahwa kadang-kadang perlu untuk mencapai kinerja yang baik. Tapi saya pikir itu perlu jauh lebih jarang daripada yang diklaim orang.
Saya membantah pro dan kontra Anda.
Anda mengklaim bahwa itu memusatkan logika bisnis Anda. Sebaliknya, saya pikir itu desentralisasi. Dalam produk yang saat ini saya kerjakan, kami menggunakan prosedur tersimpan untuk banyak logika bisnis kami. Banyak masalah kinerja kami datang dari fungsi panggilan berulang kali. Misalnya
Masalah dengan pendekatan ini adalah bahwa umumnya (mungkin ada kasus di mana ini salah) memaksa database untuk menjalankan fungsi Anda N kali, sekali per baris. Terkadang fungsi itu mahal. Beberapa basis data mendukung indeks fungsi. Tetapi Anda tidak dapat mengindeks setiap fungsi yang mungkin terhadap setiap input yang mungkin. Atau bisakah kamu?
Solusi umum untuk masalah di atas adalah mengekstrak logika dari fungsi dan menggabungkannya ke dalam kueri. Sekarang Anda telah merusak enkapsulasi dan duplikasi logika.
Masalah lain yang saya lihat adalah memanggil prosedur tersimpan dalam satu lingkaran karena tidak ada cara untuk bergabung atau memotong set hasil proc yang disimpan.
Jika Anda menarik kode dari proc bersarang, maka Anda kembali mendesentralisasi. Karena itu, Anda dipaksa untuk memilih antara enkapsulasi dan kinerja.
Secara umum, saya menemukan bahwa database buruk di:
Database bagus dalam:
Dengan mengambil operasi yang mahal seperti loop dan penguraian string dan menyimpannya di tingkat aplikasi Anda, Anda dapat secara horizontal mengukur aplikasi Anda untuk mendapatkan kinerja yang lebih baik. Menambahkan beberapa server aplikasi di belakang load balancer biasanya jauh lebih murah daripada mengatur replikasi database.
Anda benar, bagaimanapun, bahwa itu memisahkan logika bisnis Anda dari bahasa pemrograman aplikasi Anda, tetapi saya tidak melihat mengapa itu merupakan keuntungan. Jika Anda memiliki aplikasi Java, maka Anda memiliki aplikasi Java. Mengubah sekelompok kode Java ke dalam prosedur tersimpan tidak mengubah fakta bahwa Anda memiliki aplikasi Java.
Preferensi saya adalah menjaga kode basis data tetap fokus pada kegigihan. Bagaimana Anda membuat widget baru? Anda harus memasukkan ke dalam 3 tabel dan mereka harus dalam transaksi. Itu termasuk dalam prosedur tersimpan.
Menentukan apa yang dapat dilakukan untuk widget dan aturan bisnis untuk menemukan widget termasuk dalam aplikasi Anda.
sumber
Saya telah bekerja di 2 perusahaan berbeda yang memiliki visi berbeda tentang masalah ini.
Saran pribadi saya adalah menggunakan Prosedur Tersimpan ketika waktu eksekusi penting (kinerja). Karena Prosedur Tersimpan dikompilasi, jika Anda memiliki logika kompleks untuk menanyakan data, lebih baik menyimpannya di database itu sendiri. Juga, itu hanya akan mengirim data akhir ke program Anda di akhir.
Kalau tidak, saya pikir logika suatu program harus selalu dalam perangkat lunak itu sendiri. Mengapa? Karena sebuah program perlu diuji dan saya tidak berpikir ada cara mudah untuk menguji prosedur yang tersimpan. Jangan lupa, program yang tidak diuji adalah program yang buruk.
Jadi gunakan Prosedur Tersimpan dengan hati-hati, saat dibutuhkan.
sumber
Ada jalan tengah yang perlu Anda temukan. Saya telah melihat proyek-proyek yang menakutkan di mana programmer menggunakan database sebagai tidak lebih dari toko kunci / nilai yang mahal. Saya telah melihat orang lain di mana programmer gagal menggunakan kunci & indeks asing. Di ujung lain dari spektrum, saya telah melihat proyek-proyek di mana sebagian besar jika tidak semua logika bisnis diimplementasikan dalam kode database.
Seperti yang telah Anda catat, T-SQL (atau yang sederajat dalam RDBMS populer lainnya) bukan tempat terbaik untuk menjadi pengkodean logika bisnis yang kompleks.
Saya mencoba untuk membangun model data yang cukup layak, menggunakan fitur-fitur basis data untuk melindungi asumsi saya tentang model itu (yaitu, FK dan kendala), dan menggunakan kode basis data dengan hemat. Kode database berguna ketika Anda membutuhkan sesuatu (yaitu jumlah) yang sangat baik dilakukan oleh database dan dapat membantu Anda memindahkan jutaan catatan di atas kabel saat Anda tidak membutuhkannya.
sumber
Jika logika bisnis Anda melibatkan operasi yang ditetapkan, kemungkinan besar tempat yang baik untuk itu adalah dalam database karena sistem database sangat baik dalam melakukan operasi yang ditetapkan.
http://en.wikipedia.org/wiki/Set_operations_(SQL)
Jika logika bisnis melibatkan semacam perhitungan, itu mungkin termasuk di luar prosedur basis data / toko karena basis data tidak benar-benar dirancang untuk pengulangan dan penghitungan.
Meskipun ini bukan aturan yang keras dan cepat, ini adalah titik awal yang baik.
sumber
Tidak ada jawaban yang tepat untuk ini. Tergantung pada apa Anda menggunakan database. Dalam aplikasi perusahaan, Anda memerlukan logika dalam database melalui kunci asing, batasan, pemicu, dll. Karena itu adalah satu-satunya tempat di mana semua aplikasi mungkin berbagi kode. Selanjutnya, memasukkan logika yang diperlukan dalam kode umumnya berarti database tidak konsisten dan data berkualitas buruk. Itu mungkin tampak sepele bagi pengembang aplikasi yang hanya memahami cara kerja GUI, tetapi saya jamin Anda bahwa orang yang mencoba menggunakan data dalam laporan kepatuhan merasa sangat menjengkelkan dan mahal ketika mereka mendapatkan denda miliaran dolar karena memiliki data yang tidak ikuti aturan dengan benar.
Dalam lingkungan non-regulasi saat Anda tidak terlalu peduli dengan seluruh rangkaian catatan dan hanya satu atau dua aplikasi yang menyentuh database, mungkin Anda bisa lolos dengan menyimpannya dalam aplikasi.
sumber
Setelah beberapa tahun, pertanyaannya tetap penting ...
Aturan praktis sederhana untuk saya: jika itu adalah kendala logis atau ekspresi di mana-mana (pernyataan tunggal), letakkan di database (ya, kunci asing dan periksa kendala juga logika bisnis!). Jika itu prosedural, dengan mengandung loop dan cabang kondisional (dan benar-benar tidak dapat diubah menjadi ekspresi), masukkan ke dalam kode.
Hindari DB dump sampah
Upaya untuk benar-benar menempatkan semua logika bisnis dalam kode aplikasi kemungkinan akan mengubah basis data (relasional) menjadi tempat sampah, di mana desain relasional sebagian besar dihilangkan sepenuhnya, di mana data dapat memiliki keadaan tidak konsisten, dan normalisasi hilang (biasanya XML, JSON) , CSV dll. Kolom trashbin).
Logika khusus-aplikasi semacam ini mungkin merupakan salah satu alasan utama munculnya NoSQL - tentu saja dengan kelemahannya bahwa aplikasi harus mengurus semua logika itu sendiri, apa yang telah dibangun menjadi DB relasional selama beberapa dekade. Namun, database NoSQL lebih cocok untuk jenis penanganan data ini, misalnya, dokumen data mempertahankan "integritas relasional" tersirat dalam diri mereka sendiri. Untuk DB relasional, itu hanya penyalahgunaan, yang menyebabkan lebih banyak masalah.
Ekspresi (set-based) alih-alih kode prosedural
Dalam kasus terbaik, setiap kueri atau operasi data harus dikodekan sebagai ekspresi, bukan kode prosedural. Dukungan hebat untuk ini adalah ketika bahasa pemrograman mendukung ekspresi, seperti LINQ di dunia .NET (sayangnya, hanya permintaan saat ini, tidak ada manipulasi). Di sisi DB relasional, telah diajarkan untuk waktu yang lama, untuk lebih suka ekspresi pernyataan SQL daripada loop kursor prosedural. Sehingga DB dapat mengoptimalkan, melakukan operasi paralel, atau apa pun yang mungkin berguna.
Memanfaatkan mekanisme integritas data DB
Ketika datang ke RDBMS dengan Foreign Key dan Periksa kendala, kolom terhitung, mungkin pemicu dan pandangan, ini adalah tempat untuk menyimpan logika bisnis dasar dalam database. Normalisasi yang tepat membantu menjaga integritas data, untuk memastikan contoh data yang unik dan berbeda. Bahkan jika Anda harus menduplikatnya dalam kode dan DB, mekanisme dasar integritas data ini tidak boleh dihilangkan!
Prosedur Tersimpan?
Prosedur Tersimpan jarang diperlukan saat ini, karena database terus menyusun rencana eksekusi untuk SQL dan menggunakannya kembali ketika permintaan yang sama datang lagi, hanya dengan parameter yang berbeda. Jadi argumen precompile untuk SPs tidak lagi valid. Satu dapat menyimpan atau menghasilkan secara otomatis kueri SQL dalam aplikasi atau ORM, yang akan menemukan rencana kueri yang telah dikompilasi sebagian besar waktu. SQL adalah bahasa ekspresi, selama Anda tidak secara eksplisit menggunakan elemen prosedural. Jadi, dalam kasus terbaik, Anda menggunakan ekspresi kode yang dapat diterjemahkan ke dalam SQL.
Sementara sisi aplikasi, termasuk ORM yang dihasilkan, SQL, tidak lagi ada di dalam database, tidak seperti Stored Procedures, saya masih menghitungnya sebagai kode basis data. Karena masih membutuhkan SQL dan pengetahuan basis data (kecuali CRUD yang paling sederhana), dan, jika diterapkan dengan benar, kerjanya sangat berbeda dari kode prosedural yang biasanya dibuat dengan bahasa pemrograman seperti C # atau Java.
sumber
Itu benar-benar tergantung pada bisnis, budaya dan warisannya. Selain pertimbangan teknis (ini telah dibahas dari kedua sisi), jawaban yang diberikan memberitahu Anda bahwa itu berasal dari mana orang berasal. Di beberapa organisasi, data adalah raja dan DBA adalah sosok yang kuat. Ini adalah lingkungan terpusat khas Anda, pusat data dengan banyak terminal yang melekat padanya. Preferensi dalam jenis lingkungan ini jelas. Desktop dapat berubah berkali-kali secara radikal sebelum ada perubahan apa pun di pusat data dan akan ada sedikit di antaranya.
Ujung lain dari spektrum adalah arsitektur 3-tier murni. Atau mungkin multi-tier dalam bisnis yang berorientasi web. Kemungkinan Anda akan mendengar cerita yang berbeda di sini. DBA, jika ada, hanya akan menjadi pendamping yang melakukan beberapa tugas administratif.
Pengembang aplikasi zaman modern akan memiliki lebih banyak kedekatan dengan model kedua. Jika Anda tumbuh dengan sistem server-klien besar, Anda kemungkinan besar akan berada di kubu lain.
Sering ada begitu banyak faktor terkait lingkungan non-teknis yang terlibat di sini, tidak ada jawaban umum untuk pertanyaan ini.
sumber
Logika bisnis istilah terbuka untuk interpretasi. Saat membangun sistem, kami ingin memastikan integritas basis data dan isinya. Sebagai langkah pertama harus ada hibah akses pengguna yang berbeda di tempat. Sebagai contoh yang sangat sederhana, mari kita pertimbangkan aplikasi ATM.
Untuk mendapatkan saldo akun, melakukan pemilihan pada tampilan yang sesuai harus dilakukan. Tetapi untuk mentransfer dana, Anda ingin transkapsulasi dengan prosedur tersimpan. Logika bisnis tidak boleh diizinkan untuk secara langsung memperbarui tabel untuk jumlah kredit dan debit.
Dalam contoh ini, logika bisnis dapat memeriksa saldo sebelum meminta transfer atau cukup memanggil proc yang disimpan untuk transfer dan melaporkan kegagalannya. IMHO, logika bisnis, dalam contoh ini, harus memeriksa secara pre-emptive bahwa dana yang cukup tersedia dan bahwa akun target ada dan hanya kemudian meminta dana transfer. Jika debet lain terjadi antara langkah-langkah awal dan permintaan proc disimpan, hanya kemudian kesalahan akan dikembalikan.
sumber