Mengapa kendala diterapkan dalam Database? Apakah tidak akan lebih fleksibel untuk memasukkannya ke dalam kode?
Saya membaca buku pemula tentang mengimplementasikan database, jadi saya meminta ini sebagai pemula. Katakanlah saya telah mendesain database, termasuk model entitas ini:
entity type | sub-types
----------------+--------------------------------------------
Person | Employee, Student, ...
Student | Graduate, Undergraduate, ...
Employee | Teacher, Administrator, ...
Kendala saat ini:
- Orang yang terdaftar pada sistem hanya dapat menjadi Siswa atau Karyawan.
- Entitas pribadi memerlukan keunikan bilangan sosial, yang kami anggap setiap orang hanya memiliki satu nomor unik (alias, kunci utama yang cukup bagus ). (lihat # 1)
Kemudian kami memutuskan untuk menghapus nomor 1: Jika suatu hari perguruan tinggi memutuskan bahwa Teacher
( Employee
sub-tipe) dapat juga Student
, mengambil kursus di waktu luang mereka, jauh lebih sulit untuk mengubah desain basis data yang dapat memiliki ribuan, jutaan, miliaran, zillions entri daripada hanya mengubah logika dalam kode: hanya bagian yang tidak memungkinkan seseorang didaftarkan baik sebagai siswa dan karyawan.
(Ini sangat mustahil tetapi saya tidak bisa memikirkan hal lain saat ini. Rupanya itu mungkin).
Mengapa kita peduli dengan aturan bisnis dalam desain database daripada dalam kode?
# 1: Sebuah catatan 7 tahun kemudian, contoh kehidupan nyata:
Saya telah melihat pemerintah di mana karena kesalahan, SSN yang dikeluarkan digandakan: banyak orang, SSN yang sama. Mereka yang merancang DB asli pasti membuat kesalahan dengan tidak menerapkan kendala keunikan ini dalam database. (dan kemudian bug dalam aplikasi asli? beberapa aplikasi menggunakan database bersama dan tidak menyetujui tempat untuk meletakkan, memeriksa dan menegakkan batasan? ...).
Bug ini akan terus hidup dalam sistem dan semua sistem yang dikembangkan setelah itu bergantung pada database sistem asli itu, selama bertahun-tahun yang akan datang. Membaca jawaban di sini saya belajar menerapkan semua kendala, sebanyak mungkin dari mereka, dengan bijak (tidak secara membabi buta) dalam database untuk mewakili dunia fisik nyata di luar sana sebaik yang saya bisa.
sumber
Jawaban:
Beberapa kendala paling baik ditegakkan dalam database, dan beberapa yang terbaik ditegakkan dalam aplikasi.
Kendala yang paling baik ditegakkan dalam database biasanya ada karena mereka mendasar bagi struktur model data, seperti batasan kunci asing untuk memastikan bahwa suatu produk memiliki valid
category_id
.Kendala yang ditegakkan dalam suatu aplikasi mungkin tidak mendasar bagi model data, seperti semua produk FooBar harus berwarna biru - tetapi kemudian seseorang mungkin memutuskan bahwa FooBars juga bisa berwarna kuning. Ini adalah logika aplikasi yang tidak benar-benar perlu ada dalam database, meskipun Anda bisa membuat
colours
tabel terpisah dan database dapat meminta referensi produk entri yang valid dari tabel itu. TETAPI keputusan bahwa satu-satunya catatan yangcolours
memiliki nilai masihblue
akan datang dari suatu tempat di luar basis data.Pertimbangkan apa yang akan terjadi jika Anda tidak memiliki kendala dalam database, dan mengharuskan mereka untuk semua diberlakukan dalam aplikasi. Apa yang akan terjadi jika Anda memiliki lebih dari satu aplikasi yang perlu bekerja dengan data? Seperti apa data Anda jika aplikasi yang berbeda memutuskan untuk memberlakukan berbagai kendala secara berbeda?
Contoh Anda menunjukkan situasi di mana mungkin lebih bermanfaat untuk memiliki kendala dalam aplikasi daripada dalam database, tetapi mungkin ada masalah mendasar dengan model data awal yang terlalu ketat dan tidak fleksibel?
sumber
teachers_as_students
subtipe lainStudents
dan memiliki kunci asing yang merujukTeachers
, dan kunci primer yang dihasilkan sistem , bukan Sosial Nomor keamanan. Dengan cara ini, "siswa" sebenarnya adalah alias untuk seorang guru sehingga guru masih bisa mendaftar untuk mengambil kelas. Sulit untuk mengatakan dengan pasti seberapa baik ini akan bekerja tanpa melihat seluruh model data.color_products
, dancolor
, Anda mungkin akan dapat membuat drop down tambahan dengan lebih mudah - sebagian besar IDE / schema loader, mendukung fkeys berikut.Karena:
Hanya beberapa alasan yang penting bagi saya.
sumber
Data kemungkinan akan lama hidup lebih lama dari kode aplikasi. Jika aturan sangat penting untuk data yang berguna dari waktu ke waktu (seperti batasan kunci asing yang membantu menjaga integritas data), aturan itu harus ada dalam database. Kalau tidak, Anda berisiko kehilangan kendala dalam aplikasi baru yang mengenai database. Tidak hanya beberapa aplikasi memukul basis data (Termasuk beberapa yang mungkin tidak menyadari ada aturan data penting) tetapi beberapa dari mereka seperti impor data atau aplikasi pelaporan mungkin tidak dapat menggunakan lapisan data yang diatur dalam aplikasi entri data utama. Sejujurnya, kemungkinan ada bug dalam kendala jauh lebih tinggi dalam kode aplikasi dalam pengalaman saya.
Menurut pendapat pribadi saya (berdasarkan lebih dari 30 tahun berurusan dengan data dan pengalaman dengan ratusan basis data yang berbeda yang digunakan untuk berbagai tujuan) siapa pun yang tidak menempatkan kendala dalam basis data di mana mereka berada pada akhirnya akan memiliki data yang buruk. Terkadang data yang buruk sampai tidak dapat digunakan lagi. Ini terutama berlaku di mana Anda memiliki data keuangan / peraturan yang perlu memenuhi kriteria tertentu untuk diaudit.
sumber
Sebagian besar kendala integritas referensial yang diterapkan di luar basis data dapat dikalahkan, jadi jika Anda ingin data Anda memiliki integritas yang terjamin setiap saat, maka Anda harus menerapkan batasan dalam basis data. Berhenti penuh, itu saja.
Kendala tingkat aplikasi biasanya dikalahkan meskipun database membaca mekanisme konsistensi, dimana sesi tidak dapat melihat data sesi lain sampai berkomitmen.
Misalnya, dua sesi dapat mencoba memasukkan nilai yang sama ke dalam kolom yang dimaksudkan untuk menjadi unik. Mereka berdua dapat memeriksa pada saat yang sama bahwa nilainya belum ada, keduanya dapat memasukkan nilainya, dan keduanya dapat melakukan komit. Kendala unik yang diterapkan dalam database tidak akan membiarkan ini terjadi.
Omong-omong, ini bukan hal yang asing bagi para perancang bahasa aplikasi. Baca bagian 3.10 keunikan dalam Panduan Ruby on Rails: Validasi Rekaman Aktif dan Callback
sumber
Manfaat kendala yang ditegakkan oleh database:
Kesederhanaan - Mendeklarasikan kendala secara signifikan lebih sederhana daripada mendeklarasikan kendala dan menulis kode yang akan menegakkan deklarasi itu.
Akurasi - Kode yang tidak Anda tulis tidak akan pernah memiliki bug yang Anda buat. Vendor database menghabiskan waktu memastikan kode kendala mereka akurat, jadi Anda tidak perlu melakukannya.
Kecepatan - Aplikasi Anda tidak akan pernah memiliki distribusi lebih dari basis data yang digunakannya. Vendor basis data menghabiskan waktu memastikan kode kendala mereka efisien, jadi Anda tidak perlu melakukannya. Basis data itu sendiri juga memiliki akses lebih cepat ke data daripada yang bisa dilakukan oleh suatu aplikasi terlepas dari seberapa efisiennya.
Penggunaan kembali - Anda dapat mulai dengan satu aplikasi pada satu platform, tetapi mungkin tidak tetap seperti itu. Bagaimana jika Anda perlu mengakses data dari OS yang berbeda, perangkat keras yang berbeda, atau dari antarmuka suara? Dengan memiliki kendala dalam database, kode ini tidak harus ditulis ulang untuk platform baru dan tidak pernah harus di-debug untuk akurasi atau profil untuk kecepatan.
Kelengkapan - Aplikasi memberlakukan batasan saat data dimasukkan ke dalam basis data dan akan membutuhkan upaya tambahan untuk memverifikasi data yang lebih tua akurat atau untuk memanipulasi data yang sudah ada dalam basis data.
Panjang Umur - Platform database Anda kemungkinan akan hidup lebih lama dari aplikasi tertentu.
sumber
Mengapa kendala diterapkan di server? Karena Anda tidak dapat memaksa orang jahat untuk menggunakan klien Anda.
Untuk memperjelas, jika Anda hanya melakukan pemrosesan aturan bisnis dalam aplikasi klien Anda maka seseorang yang menggunakan alat lain dapat terhubung ke server database dan melakukan apa pun yang mereka inginkan tanpa dibatasi oleh aturan bisnis Anda dan pemeriksaan integritas. Menghentikan siapa pun dari menggunakan alat sewenang-wenang di mana pun di jaringan sangat sulit.
Jika Anda melakukan pemeriksaan integritas pada server database maka setiap upaya untuk mengakses data, apa pun alatnya, akan dibatasi oleh aturan Anda.
sumber
Beberapa jawaban bagus di sini, dan dengan risiko mengulang pemikiran lain:
UPDATE
pernyataan langsung terhadap basis data, bagaimana aplikasi Anda mencegah perubahan yang tidak valid? Masalah lain dengan aturan bisnis dalam aplikasi adalah bahwa kompilasi / penempatan ulang bisa sulit, terutama untuk aplikasi terdistribusi di mana dimungkinkan bahwa tidak semua orang akan mendapatkan pembaruan pada saat yang sama. Dan akhirnya, mengubah aturan bisnis dalam aplikasi sama sekali tidak tentang data yang sudah ada yang melanggar aturan baru - jika Anda menambahkan kendala baru ke data, Anda perlu memperbaiki data.Dalam kasus yang Anda sebutkan secara eksplisit, di mana Anda tiba-tiba mengizinkan sesuatu yang sebelumnya tidak diizinkan, ini sebenarnya bukan masalah - Anda menghilangkan kendala apa pun yang memaksanya, terlepas dari di mana itu ada. Dalam kasus sebaliknya, di mana tiba-tiba guru tidak lagi diizinkan menjadi siswa, Anda berpotensi memiliki banyak data untuk dibersihkan, lagi terlepas dari mana kendala yang ada sebelumnya.
sumber
Basis data dapat memeriksa kendala secara efektif. Lebih baik daripada kode.
Batasan integritas membantu basis data untuk menemukan rencana pelaksanaan yang efektif
Aplikasi melihat tampilan yang konsisten, oleh karena itu hampir tidak dapat menjamin keunikan. Sementara database juga bisa melihat data yang tidak berkomitmen.
sumber
Jawaban singkat ... untuk menjaga integritas data (yaitu akurasi dan validitas).
Pengecualian ...
Jika database hanya menyimpan data aplikasi tunggal untuk pengguna tunggal, seperti di sebagian besar database Sqlite, mungkin tidak memerlukan kendala. Bahkan, mereka biasanya tidak, sehingga menjaga waktu akses begitu cepat sehingga tidak terukur.
Untuk yang lainnya ...
Database selalu melayani dua tuan yang saya sebut editor dan pengguna .
Editor sebagian besar memasukkan data ke dalam basis data dan mengambil data satu atau sejumlah kecil catatan sekaligus. Perhatian utama mereka adalah akses yang cepat dan akurat ke semua data terkait dan penyimpanan perubahan yang cepat dan andal.
Sebagian besar pengguna mengambil data dan paling peduli dengan akses cepat ke informasi akurat yang tidak diragukan lagi. Mereka sering membutuhkan berbagai hitungan, agregasi dan daftar yang digunakan untuk menghasilkan tumpukan tebal kertas greenbar kertas ikonik tetapi biasanya berakhir di halaman web hari ini.
Proyek pengembangan basis data hampir selalu dimulai atas perintah Pengguna , tetapi desainnya didorong oleh kebutuhan entri data dan catatan waktu. Editor pada . Dengan demikian, pengembang yang tidak berpengalaman sering merespons kebutuhan mendesak akan kecepatan (terutama pengembangan ) dengan tidak menempatkan kendala dalam database.
Jika satu dan hanya satu aplikasi yang akan digunakan untuk membuat perubahan pada data untuk seluruh umur database, dan aplikasi itu dikembangkan oleh satu atau sejumlah kecil individu yang terkoordinasi dengan baik, maka itu mungkin masuk akal untuk mengandalkan aplikasi untuk memastikan integritas data.
Namun, sebanyak kita berpura-pura dapat memprediksi masa depan, kita tidak bisa.
Upaya menghasilkan basis data apa pun terlalu berharga untuk dibuang begitu saja. Seperti rumah, basis data akan diperluas, diubah, dan direnovasi berkali-kali. Bahkan ketika itu sepenuhnya diganti, semua data akan dimigrasi ke database baru sambil mempertahankan semua aturan dan hubungan bisnis yang lama.
Kendala menerapkan aturan-aturan dan hubungan-hubungan dalam bentuk singkat, deklaratif dalam mesin database itu sendiri di mana mereka mudah diakses. Tanpa mereka, pengembang selanjutnya harus menuangkan melalui program aplikasi untuk merekayasa balik aturan tersebut. Semoga berhasil!
Ini, by-the-way, persis apa yang harus dilakukan oleh programmer mainframe COBOL karena database besar itu sering dibuat sebelum kita memiliki mesin dan kendala relasional. Bahkan jika bermigrasi ke sistem modern seperti DB2 IBM, kendala terkadang tidak sepenuhnya diterapkan karena logika aturan lama, yang mungkin terkandung dalam serangkaian program "kumpulan" COBOL, mungkin berbelit-belit sehingga tidak praktis untuk dikonversi. Alih-alih, alat otomatis dapat digunakan untuk mengubah COBOL lama menjadi versi yang lebih baru dengan antarmuka ke mesin relasional baru dan dengan sedikit penyesuaian, integritas data dipertahankan ... sampai aplikasi baru ditulis yang secara halus merusak segalanya dan perusahaan diseret. ke pengadilan untuk, katakanlah, menyita ribuan pemilik rumah yang seharusnya tidak mereka miliki.
sumber
Selain komentar lain ...
Jika / ketika Anda memiliki database di mana setiap tabel yang diberikan dapat diperbarui oleh satu atau lebih aplikasi atau jalur kode maka menempatkan batasan yang sesuai dalam database berarti bahwa aplikasi Anda tidak akan menduplikasi kode kendala "sama". Ini menguntungkan Anda dengan menyederhanakan pemeliharaan (mengurangi jumlah tempat untuk berubah jika / ketika ada perubahan model data) dan memastikan bahwa kendala diterapkan secara konsisten terlepas dari aplikasi yang memperbarui data.
sumber
Secara pribadi, saya pikir lebih mudah untuk membuat dan mengubah kendala daripada membuat pemicu, misalnya, yang akan menjadi salah satu cara untuk menegakkan aturan bisnis Anda menggunakan kode sumber.
Pemicu juga cenderung lebih mudah dibawa-bawa, karena biasanya ditulis dalam bahasa khusus vendor, seperti PL / SQL.
Tetapi jika kendala tidak memenuhi kebutuhan Anda, Anda selalu dapat menggunakan pemicu untuk menegakkan aturan bisnis Anda.
sumber
Mereka harus selalu diterapkan dalam database terlebih dahulu karena,
varchar(5)
tipe, ada kemungkinan besar Anda dapat menemukan skema memuat ORM untuk bahasa spesifik Anda yang memetakan jenis bahasa ke tipe skema, dan merakit sendiri kendala ukuran.DBIx for Perl is one such schema loader
; di sini ada satu lagi untuk Kerangka Entitas . Kemampuan loader ini berbeda-beda, tetapi apa pun yang mereka dapat berikan adalah awal yang baik untuk memastikan integritas dalam aplikasi tanpa perjalanan ke database.sumber