Katakanlah Anda menulis aplikasi yang dapat dikonfigurasi oleh pengguna. Untuk menyimpan "data konfigurasi" ini ke dalam basis data, dua pola biasanya digunakan.
The meja tunggal-baris
CompanyName | StartFullScreen | RefreshSeconds | ... ---------------+-------------------+------------------+-------- ACME Inc. | true | 20 | ...
The nama-nilai-pair meja
ConfigOption | Value -----------------+------------- CompanyName | ACME Inc. StartFullScreen | true (or 1, or Y, ...) RefreshSeconds | 20 ... | ...
Saya telah melihat kedua opsi di alam liar, dan keduanya memiliki kelebihan dan kekurangan yang jelas, misalnya:
- Tabel baris tunggal membatasi jumlah opsi konfigurasi yang dapat Anda miliki (karena jumlah kolom dalam satu baris biasanya terbatas). Setiap opsi konfigurasi tambahan memerlukan perubahan skema DB.
- Dalam tabel pasangan nama-nilai semuanya "diketik secara ketat" (Anda harus menyandikan / mendekode parameter Boolean / Tanggal / dll.)
- (masih banyak lagi)
Apakah ada beberapa konsensus dalam komunitas pembangunan tentang opsi mana yang lebih disukai?
Jawaban:
Saya pribadi lebih suka tabel baris tunggal untuk banyak hal. Memang benar bahwa itu kurang fleksibel, kecuali jika Anda mengharapkan perilaku dinamis, itu sangat dapat diterima untuk menambahkan kolom tambahan nanti jika Anda perlu. Di satu sisi, itu setara dengan menggunakan kamus / peta untuk menahan pasangan nama-nilai vs memiliki anggota kelas saat pemrograman. Memang, ini bukan metafora yang sempurna, tetapi banyak keuntungan dan kerugiannya paralel ketika Anda memikirkannya.
Jadi apakah Anda akan menggunakan kamus / peta di atas anggota kelas? Mungkin tidak kecuali Anda memiliki alasan untuk berpikir bahwa jumlah data yang akan diwakili sepenuhnya dapat disesuaikan, seperti memiliki tabel pasangan nama-nilai.
sumber
Saya biasanya pergi dengan opsi 2 TAPI saya punya beberapa kolom untuk menegakkan tipe data
Opsi 1 Memiliki Manfaat tambahan yang Anda dapat dengan mudah "Swap" seluruh Konfigurasi dengan menambahkan
Active
Kolom.sumber
activatedOn
timestamp, jadi Anda bisa tahu kapan itu diaktifkan. Dan jika Anda pergi dengan opsi 2 ... apa yang terjadi jika akhirnya menyimpan nilai dalam beberapa kolom (atau itu oracle, di mana (tampaknya) nol dan string kosong adalah setara)?Bagi saya, apakah Anda menggunakan satu baris atau EAV tergantung pada bagaimana Anda ingin mengkonsumsinya.
Kekuatan EAV adalah bahwa data baru dapat ditambahkan tanpa perubahan struktur. Ini berarti bahwa jika Anda menginginkan nilai konfigurasi baru, Anda cukup menambahkannya ke tabel dan menariknya ke tempat yang Anda inginkan dalam kode, dan Anda tidak perlu menambahkan bidang baru ke domain, skema, pemetaan, permintaan DAL , dll.
Kekurangannya adalah bahwa ia hanya memiliki struktur paling sederhana, yang mengharuskan Anda untuk berurusan dengan data secara pesimistis. Setiap penggunaan nilai konfigurasi apa pun harus mengharapkan nilai tidak ada, atau tidak dalam format yang tepat, dan berperilaku sesuai ketika tidak. Nilai konfigurasi mungkin tidak dapat diuraikan menjadi ganda, atau int, atau char. Mungkin nol. mungkin tidak ada baris untuk nilai sama sekali. Cara-cara di sekitar ini biasanya memerlukan satu nilai "default" yang valid untuk ada untuk semua nilai konfigurasi dari jenis kode tertentu ( sangat jarang; lebih sering nilai default sama bermasalah untuk mengkonsumsi kode seperti tidak ada sama sekali), atau untuk menyimpan kamus hardcoded dari nilai-nilai default (yang harus berubah setiap kali kolom baru ditambahkan, membuat keunggulan utama penyimpanan EAV cukup diperdebatkan).
Satu baris lebar adalah kebalikannya. Anda memetakannya ke satu instance objek Konfigurasi dengan bidang / properti untuk setiap nilai konfigurasi yang ada. Anda tahu persis apa tipe nilai-nilai itu harus pada waktu kompilasi, dan Anda "gagal cepat" di DAL jika kolom konfigurasi tidak ada atau tidak memiliki nilai tipe yang tepat, memberi Anda satu tempat untuk menangkap pengecualian berdasarkan pada masalah pengambilan konfigurasi / hidrasi.
Kerugian utama adalah bahwa perubahan struktural diperlukan untuk setiap nilai baru; kolom DB baru, kolom baru di DAL (baik pemetaan atau kueri SQL / SP), kolom domain baru, semua yang diperlukan untuk menguji penggunaan dengan benar.
Situasi yang tepat untuk menggunakan salah satu dari ini adalah situasi di mana kerugian dikurangi. Bagi saya, sebagian besar situasi untuk pengkodean konfigurasi telah menyerukan implementasi baris tunggal. Ini terutama karena jika Anda memperkenalkan nilai konfigurasi yang sama sekali baru yang mengatur perilaku beberapa bagian dari program Anda, Anda harus mengubah kode untuk menggunakan nilai konfigurasi baru; mengapa tidak mampir ke objek konfigurasi dan menambahkan nilai yang akan digunakan?
Singkatnya, skema EAV untuk menyimpan konfigurasi benar-benar tidak menyelesaikan masalah yang ingin diselesaikan, dan sebagian besar solusi untuk masalah yang dihadapinya melanggar KERING.
sumber
Khusus untuk nilai konfigurasi, saya akan mengatakan - pergi dengan satu baris. Kecuali jika Anda saat ini sedang menjalani pengembangan, seberapa sering kolom itu akan berubah?
Mungkin lebih baik untuk mengamankan tipe data dari nilai , daripada kode untuk ekstensibilitas yang kemungkinan besar tidak Anda miliki di waktu henti antara rilis besar (r). Selain itu, menambahkan atau menghapus satu kolom hanyalah tentang migrasi termudah yang ada. Saya tidak melihat sakit kepala ketika membuat opsi konfigurasi baru.
Selain itu, Anda mengatakan "pengguna" dapat mengonfigurasi opsi ini, tanpa memberi batasan. Apakah itu konfigurasi per pengguna? Jika demikian, saya akan berpendapat lebih kuat lagi bahwa opsi konfigurasi harus ada di kolom - satu baris per pengguna. Ini akan menghemat banyak sakit kepala perawatan nanti.
sumber
Jika klien Anda dapat memproses fragmen JSON (yang bukan hanya array dan kamus, tetapi juga string, angka, boolean, nilai nol) maka Anda dapat memiliki tabel multi-baris dengan nama opsi dan nilai string yang berisi JSON. Itu memungkinkan Anda untuk juga menyimpan nilai terstruktur, dan kode untuk memproses ini seharusnya sudah ada di sana.
Jika klien Anda tidak dapat memproses fragmen JSON, dapatkan klien baru.
sumber
Pro baris tunggal: Didefinisikan dengan baik. Cons: Mengubah konfigurasi bisa sangat menyebalkan. Migrasi DB dll.
Entity-Value Pro: Sangat fleksibel, mendukung pengembangan konfigurasi Anda. Kekurangan: Integritas referensial? Pemeriksaan lebih lanjut dalam kode Anda untuk melihat apakah properti itu ada sebelum Anda dapat melakukan apa pun di sana.
Saya akan mengambil pendekatan 2 yang didukung oleh db non-relasional seperti Mongo. Jika ada sesuatu yang bisa Anda yakini, perubahannya.
sumber
Gunakan keduanya!
Urutkan opsi apa yang dapat memiliki banyak instance, dan opsi apa yang generik.
Tabel baris tunggal (konfigurasi)
Tabel pasangan nama-nilai (opsi)
Saya pikir ini lebih fleksibel.
sumber