Saya telah melihat sejumlah pertanyaan, seperti ini , meminta saran tentang cara menyimpan enum di DB. Tetapi saya heran mengapa Anda melakukan itu. Jadi katakanlah saya memiliki entitas Person
dengan gender
bidang, dan Gender
enum. Kemudian, tabel orang saya memiliki jenis kelamin kolom.
Selain alasan yang jelas untuk menegakkan kebenaran, saya tidak melihat mengapa saya akan membuat tabel tambahan gender
untuk memetakan apa yang sudah saya miliki dalam aplikasi saya. Dan saya tidak begitu suka duplikasi itu.
Jawaban:
Mari kita ambil contoh lain yang tidak terlalu sarat dengan konsepsi dan harapan. Saya punya enum di sini, dan itu adalah serangkaian prioritas untuk bug.
Nilai apa yang Anda simpan dalam basis data?
Jadi, saya bisa menyimpan
'C'
,'H'
,'M'
, dan'L'
dalam database. Atau'HIGH'
dan seterusnya. Ini memiliki masalah data yang diketik dengan ketat . Ada satu set nilai valid yang diketahui, dan jika Anda tidak menyimpan set itu dalam database, mungkin sulit untuk bekerja dengannya.Mengapa Anda menyimpan data dalam kode?
Anda punya
List<String> priorities = {'CRITICAL', 'HIGH', 'MEDIUM', 'LOW'};
atau sesuatu yang berpengaruh dalam kode. Ini berarti bahwa Anda memiliki berbagai pemetaan data ini ke format yang tepat (Anda memasukkan semua huruf besar ke dalam basis data, tetapi Anda menampilkannya sebagaiCritical
). Kode Anda sekarang juga sulit dilokalkan. Anda telah mengikat representasi basis data gagasan ke string yang disimpan dalam kode.Di mana pun Anda perlu mengakses daftar ini, Anda harus memiliki duplikasi kode atau kelas dengan sekelompok konstanta. Tak satu pun dari itu pilihan yang baik. Orang juga tidak boleh lupa bahwa ada aplikasi lain yang dapat menggunakan data ini (yang dapat ditulis dalam bahasa lain - aplikasi web Java memiliki sistem pelaporan Crystal Reports yang digunakan dan data pekerjaan batch Perl ke dalamnya). Mesin pelaporan perlu mengetahui daftar data yang valid (apa yang terjadi jika tidak ada yang ditandai dalam
'LOW'
prioritas dan Anda perlu tahu bahwa itu adalah prioritas yang valid untuk laporan?), Dan pekerjaan batch akan memiliki informasi tentang apa yang valid nilai adalah.Secara hipotetis, Anda mungkin mengatakan "kami adalah toko satu bahasa - semuanya ditulis dalam Java" dan memiliki .jar tunggal yang berisi informasi ini - tetapi sekarang ini berarti bahwa aplikasi Anda digabungkan secara erat satu sama lain dan .jar yang berisi data. Anda harus merilis bagian pelaporan dan bagian pembaruan kumpulan bersama dengan aplikasi web setiap kali ada perubahan - dan berharap rilis itu berjalan dengan lancar untuk semua bagian.
Apa yang terjadi ketika bos Anda menginginkan prioritas lain?
Bosmu datang hari ini. Ada prioritas baru -
CEO
. Sekarang Anda harus pergi dan mengubah semua kode dan melakukan kompilasi dan penempatan kembali.Dengan pendekatan 'enum-in-the-table', Anda memperbarui daftar enum untuk memiliki prioritas baru. Semua kode yang mendapat daftar menariknya dari database.
Data jarang berdiri sendiri
Dengan prioritas, data kunci ke tabel lain yang mungkin berisi informasi tentang alur kerja, atau siapa yang dapat menetapkan prioritas ini atau yang lainnya.
Kembali ke jenis kelamin seperti yang disebutkan dalam pertanyaan sebentar: Jenis kelamin memiliki tautan ke kata ganti yang digunakan:
he/his/him
danshe/hers/her
... dan Anda ingin menghindari pengkodean yang keras ke dalam kode itu sendiri. Dan kemudian bos Anda datang dan Anda perlu menambahkan Anda memiliki'OTHER'
jenis kelamin (untuk membuatnya sederhana) dan Anda perlu menghubungkan jenis kelamin ini denganthey/their/them
... dan bos Anda melihat apa yang dimiliki Facebook dan ... yah, ya.Dengan membatasi diri Anda pada bit data yang diketik secara ketat daripada tabel enum, Anda sekarang harus mereplikasi string itu di banyak tabel lain untuk menjaga hubungan ini antara data dan bit lainnya.
Bagaimana dengan datastore lain?
Di mana pun Anda menyimpan ini, prinsip yang sama ada.
priorities.prop
,, yang memiliki daftar prioritas. Anda membaca daftar ini dari file properti.Anda bisa memiliki database toko dokumen (seperti CouchDB ) yang memiliki entri untuk
enums
(dan kemudian menulis fungsi validasi dalam JavaScript ):Anda dapat memiliki file XML dengan sedikit skema:
Ide intinya sama. Menyimpan data itu sendiri adalah tempat daftar nilai yang valid perlu disimpan dan ditegakkan. Dengan menempatkannya di sini, lebih mudah untuk memberi alasan tentang kode dan data. Anda tidak perlu khawatir untuk secara defensif memeriksa apa yang Anda miliki setiap waktu (apakah ini huruf besar? Atau lebih rendah? Mengapa ada
chritical
jenis dalam kolom ini? Dll ...) karena Anda tahu apa yang Anda dapatkan dari datastore adalah persis apa yang diharapkan oleh datastore Anda untuk dikirim sebaliknya - dan Anda dapat meminta datastore untuk daftar nilai yang valid.Dibawa pulang
Himpunan nilai yang valid adalah data , bukan kode. Anda tidak perlu berusaha untuk DRY kode - tetapi masalah duplikasi adalah bahwa Anda menduplikasi data yang dalam kode, daripada menghormati tempatnya sebagai data dan menyimpannya dalam database.
Itu membuat menulis beberapa aplikasi terhadap datastore lebih mudah dan menghindari memiliki contoh di mana Anda akan perlu menyebarkan segala sesuatu yang tergabung erat dengan data itu sendiri - karena Anda belum menambahkan kode Anda ke data.
Itu membuat pengujian aplikasi lebih mudah karena Anda tidak perlu menguji ulang seluruh aplikasi ketika
CEO
prioritas ditambahkan - karena Anda tidak memiliki kode apa pun yang peduli tentang nilai aktual prioritas.Mampu beralasan tentang kode dan data secara independen dari satu sama lain membuatnya lebih mudah untuk menemukan dan memperbaiki bug saat melakukan pemeliharaan.
sumber
Menurut Anda, manakah di antara ini yang lebih cenderung menghasilkan kesalahan saat membaca kueri?
Atau
Orang-orang membuat tabel enum dalam SQL karena mereka menemukan yang terakhir lebih mudah dibaca - menyebabkan lebih sedikit kesalahan dalam menulis dan memelihara SQL.
Anda dapat membuat gender menjadi string secara langsung
Person
, tetapi kemudian Anda harus mencoba dan menegakkan kasus. Anda juga dapat meningkatkan hit penyimpanan untuk tabel dan waktu kueri karena perbedaan antara string dan integer tergantung pada seberapa hebat DB Anda dalam mengoptimalkan berbagai hal.sumber
Saya tidak percaya orang belum menyebutkan ini.
Kunci Asing
Dengan menyimpan enum di database Anda, dan menambahkan kunci asing di atas meja yang berisi nilai enum Anda memastikan bahwa tidak ada kode yang pernah memasukkan nilai yang salah untuk kolom itu. Ini membantu integritas data Anda dan merupakan alasan paling jelas IMO Anda harus memiliki tabel untuk enum.
sumber
Saya di kamp yang setuju dengan Anda. Jika Anda menyimpan Gender enum dalam kode Anda dan tblGender dalam basis data Anda, Anda mungkin akan mengalami masalah ketika waktu pemeliharaan. Anda harus mendokumentasikan bahwa kedua entitas ini harus memiliki nilai yang sama dan dengan demikian setiap perubahan yang Anda buat untuk satu Anda juga harus membuat yang lain.
Anda kemudian harus memberikan nilai enum ke prosedur tersimpan Anda seperti:
Tetapi pikirkan bagaimana Anda akan melakukan ini jika Anda menyimpan nilai-nilai ini dalam tabel database:
Memang basis data relasional dibangun dengan mempertimbangkan bergabung, tetapi kueri mana yang lebih mudah dibaca?
Berikut ini contoh kueri lainnya:
Bandingkan dengan ini:
Berikut ini contoh permintaan lain:
Perhatikan bahwa dalam contoh ini, Anda harus mengubah sel gender dalam hasil Anda dari int ke enum. Namun konversi ini mudah. Bandingkan dengan ini:
Semua pertanyaan ini lebih kecil dan lebih dapat dikelola ketika pergi dengan ide Anda untuk menjaga definisi enum dari database.
sumber
Saya akan membuat tabel Jenis Kelamin karena dapat digunakan dalam analisis data. Saya bisa mencari semua Pria atau Wanita di database untuk menghasilkan laporan. Semakin banyak cara Anda melihat data, semakin mudah menemukan informasi tren. Jelas, ini adalah pencacahan yang sangat sederhana, tetapi untuk pencacahan yang rumit (seperti negara di dunia, atau negara bagian), membuatnya lebih mudah untuk menghasilkan laporan khusus.
sumber
Pertama, Anda perlu memutuskan apakah basis data hanya akan digunakan oleh satu aplikasi atau apakah ada potensi beberapa aplikasi untuk menggunakannya. Dalam beberapa kasus database tidak lebih dari format file untuk suatu aplikasi (database SQLite sering dapat digunakan dalam hal ini). Dalam hal ini sedikit menduplikasi definisi enum sebagai tabel sering kali baik dan mungkin lebih masuk akal.
Namun begitu Anda ingin mempertimbangkan kemungkinan memiliki beberapa aplikasi mengakses database, maka tabel untuk enum sangat masuk akal (jawaban lain masuk ke mengapa lebih terinci). Hal lain yang perlu dipertimbangkan adalah Anda atau pengembang lain ingin melihat data basis data mentah. Jika demikian, ini dapat dianggap sebagai penggunaan aplikasi lain (hanya di mana pengukur lab adalah SQL mentah).
Jika Anda memiliki enum yang didefinisikan dalam kode (untuk kode yang lebih bersih dan kompilasi waktu pengecekan) serta tabel dalam database, saya akan merekomendasikan menambahkan tes unit untuk memverifikasi bahwa keduanya sinkron.
sumber
Ketika Anda memiliki kode enumerasi yang digunakan untuk mendorong logika bisnis dalam kode Anda masih harus membuat tabel untuk mewakili data dalam DB karena berbagai alasan yang dijelaskan di atas / di bawah. Berikut adalah beberapa tips untuk memastikan bahwa nilai DB Anda tetap sinkron dengan nilai kode:
Jangan jadikan bidang ID pada tabel sebagai kolom Identitas. Sertakan ID dan Deskripsi sebagai bidang.
Lakukan sesuatu yang berbeda dalam tabel yang membantu pengembang tahu bahwa nilai-nilai semi-statis / terikat pada penghitungan kode. Di semua tabel pencarian lainnya (biasanya di mana nilai dapat ditambahkan oleh pengguna) Saya biasanya memiliki LastChangedDateTime dan LastChangedBy, tetapi tidak memilikinya pada tabel terkait enum membantu saya mengingat bahwa mereka hanya dapat diubah oleh pengembang. Dokumentasikan ini.
Buat kode verifikasi yang memeriksa untuk melihat bahwa setiap nilai dalam enumerasi berada di tabel terkait, dan hanya nilai-nilai itu yang ada di tabel terkait. Jika Anda memiliki aplikasi otomatis "tes kesehatan" yang menjalankan post-build, lakukanlah di sana. Jika tidak, buat kode berjalan secara otomatis saat startup aplikasi setiap kali aplikasi berjalan di IDE.
Buat produksi menghasilkan skrip SQL yang melakukan hal yang sama, tetapi dari dalam DB. Jika dibuat dengan benar mereka juga akan membantu dengan migrasi lingkungan.
sumber
Tergantung juga pada siapa yang mengakses data. Jika Anda hanya memiliki satu aplikasi yang mungkin baik-baik saja. Jika Anda menambahkan data warehouse atau sistem pelaporan. Mereka perlu tahu apa artinya kode itu, apa versi kode yang dapat digunakan kembali manusia.
Biasanya, tabel tipe tidak akan diduplikasi sebagai enum dalam kode. Anda bisa memuat tabel tipe dalam daftar yang di-cache.
Seringkali, ketik datang dan pergi. Anda memerlukan tanggal kapan tipe baru ditambahkan. Ketahui kapan jenis tertentu dihapus. Tampilkan hanya saat dibutuhkan. Bagaimana jika klien ingin "transgender" sebagai jenis kelamin tetapi klien lain tidak? Semua informasi ini paling baik disimpan dalam database.
sumber