Cukup banyak aplikasi yang membutuhkan catatan di tabel mereka untuk memiliki status, seperti 'lengkap', 'konsep', 'dibatalkan'. Apa cara terbaik untuk menyimpan status ini? Untuk menggambarkan apa yang saya maksudkan di sini adalah contoh * sangat singkat).
Saya memiliki aplikasi Blog sederhana dan setiap posting memiliki status salah satu: diterbitkan, konsep, atau tertunda.
Cara saya melihatnya ada 2 cara untuk memodelkan ini dalam database.
- Tabel Posting memiliki bidang teks yang menyertakan teks status.
- Tabel Posting memiliki bidang status yang berisi ID catatan di tabel PostStatus
Contoh Blog di sini adalah contoh yang sangat sederhana. Di mana enum (jika didukung) mungkin cukup. Namun saya ingin tanggapan terhadap pertanyaan untuk memperhitungkan bahwa daftar status dapat berubah kapan saja, sehingga lebih banyak yang dapat ditambahkan atau dihapus.
Adakah yang bisa menjelaskan kelebihan / kekurangan masing-masing?
Bersulang!
Pilihan awal saya tentang ini adalah bahwa lebih baik menggunakan tabel lain dan mencari status sebagai yang lebih baik untuk normalisasi dan saya selalu diajarkan bahwa normalisasi baik untuk database
sumber
Jawaban:
Menyimpan status sebagai indeks ke tabel lain adalah komplikasi yang tidak perlu. Simpan status langsung di tabel dengan cara yang dapat dibaca. Dalam kode aplikasi gunakan konstanta atau tipe enumerasi. Ini akan menghasilkan kode aplikasi yang lebih sederhana dan memudahkan debugging pada lapisan data.
Ini tidak mendenormalisasi data, itu hanya mengubah representasi. Jika database mendukung enumerasi secara langsung, maka gunakan itu. Kalau tidak, gunakan kendala untuk membatasi nilai kolom. Anda juga akan memiliki batasan: batasan langsung pada nilai kolom, atau batasan kunci asing.
Ya, Anda mungkin harus menyajikan status secara berbeda kepada pengguna yang berbeda. Itu adalah masalah presentasi, harus diselesaikan di lapisan presentasi, bukan lapisan kegigihan.
sumber
Menyimpan teks status adalah IMO bukan ide yang baik, karena seseorang mungkin memutuskan bahwa "selesai" harus disebut "selesai" dan kemudian Anda harus memperbarui database Anda, lihat melalui program jika seseorang melakukan hardcode pada teks dll.
Apa yang saya lihat di banyak program adalah kode numerik (1 = baru, 2 = konsep, 3 = validasi, 4 = selesai, 99 = dibatalkan) atau kode alfanumerik pendek ("BARU", "DRA", "INV "," COM "," CAN "). Yang kemudian membuat kode (dalam program atau dalam database) lebih mudah dibaca oleh manusia, yang umumnya merupakan hal yang baik. Di sisi lain, kode numerik memudahkan untuk melakukan perbandingan "lebih besar dari" atau "lebih kecil dari", misalnya
sumber
status.draft=Draught
Tiga aturan basis data relasional:
Jadi pertanyaan Anda menjawab sendiri. Simpan status di dalam tabel itu sendiri dan gunakan GUID / UUID sebagai id Anda . GUID yang diindeks sangat cepat, dan memperbaiki masalah yang intrinsik dengan penambahan angka. Dengan id Anda dapat melakukan hal-hal keren seperti meminta DB untuk semua posting selesai menggunakan id, dan karena Anda bekerja dalam paradigma db relasional, itu sangat cepat. Jika Anda hanya memiliki bidang, DB harus mengulang setiap baris dan melakukan perbandingan teks, mungkin dengan munging, dan itu sangat lambat.
Nama status kiriman dapat berubah, info lebih lanjut tentang status kiriman dapat dimasukkan ke dalam tabel, semuanya hanya berfungsi jika Anda menjadi normal .
Misalnya, Anda dapat menambahkan level status sebagai info tambahan, yang memungkinkan perbandingan amunisi disebutkan. Tetapi mereka tidak bergantung pada kunci untuk penentuan posisi, memungkinkan pengaturan ulang tingkat status tanpa merusak integritas DB. Anda juga dapat memasukkan level tambahan, yang merupakan tipuan jika Anda memiliki level yang terkait dengan kunci peningkatan otomatis.
sumber
Ya, Anda harus menggunakan opsi 2, memiliki tabel PostStatus.
Terlepas dari semua kelebihan yang disebutkan dalam jawaban lain.
Ingatlah bahwa status perlu ditambahkan atau dihapus, Anda dapat memiliki kolom "diaktifkan" di tabel PostStatus, jadi jika status dihapus tandai kolom "diaktifkan" sebagai "N", dengan cara itu Anda akan dapat menambah atau menghapus status dan juga catatan yang ada akan tetap tanpa masalah.
sumber
Saya ingin menambahkan jawaban yang berwawasan luas bahwa untuk normalisasi penuh, perubahan status suatu entitas sebenarnya dimodelkan dalam entitas yang terpisah, misalnya bernama 'statusChange'.
Anda perlu bergabung ekstra dengan entitas statusChange, tetapi Anda memenangkan kemungkinan menambahkan informasi tambahan, seperti aktor yang melakukan perubahan, kemungkinan komentar tentang mengapa perubahan itu terjadi dan tanggal di mana statusChange dilakukan dan mungkin bahkan ketika itu menjadi efektif.
sumber
Menggunakan teks untuk status dalam tabel catatan mungkin bukan ide yang baik karena ini dapat berubah dan akan sulit untuk melakukan pemeriksaan integritas data apa pun pada penyisipan / pembaruan. Jika Anda menggunakan DBMS dengan tipe data enum, Anda dapat menggunakan ini (kinerja mungkin tidak akan terganggu ... tergantung).
Jika status Anda memerlukan metadata apa pun (deskripsi, dibuat oleh, nama yang bersahabat, ...) Anda harus menyimpan status di tabel terpisah dan memiliki kunci status di tabel catatan Anda (pastikan Anda menggunakan kunci asing). ID tidak harus berupa angka, hanya PK dari tabel status. Juga, jika status berada di tabel mereka sendiri, Anda dapat membagikannya di seluruh tipe rekaman (tabel) jika berlaku. Saya tidak akan khawatir tentang masalah kinerja dengan GABUNG ke tabel status.
Apa pun yang Anda lakukan, pastikan Anda menghindari status ajaib (1 untuk aktif, 2 untuk dihapus, ...). Ini bergantung pada dokumentasi dan tradisi yang selalu memiliki kecenderungan untuk tersesat pada timeline yang cukup besar. Jika Anda menggunakan id numerik sama sekali, pastikan ada hubungan tekstual di suatu tempat di db Anda.
sumber
Tergantung pada tujuan desain database.
Jika Anda mendesain database hanya untuk mendukung aplikasi (mis. Objek (kode) adalah master semua) maka menggunakan enumerasi (atau enumerasi psuedo untuk kelas yang tidak mendukungnya) dan menyimpan nama enum adalah ide bagus karena Anda masih mengontrol nilai-nilai yang diizinkan melalui enum dan Anda juga membuat tabel sedikit lebih mudah dibaca ketika Anda dipaksa untuk melihat data mentah (yang tidak sering jika kode sebenarnya mengatur semua). Tetapi jika enumerasi ditandai. Maka saya biasanya menyimpan nilai enum (integer).
sumber
Statusnya sangat penting, setiap kali Anda mendapatkan info kiriman, Anda harus mendapatkan statusnya, atau Anda ingin memfilter kiriman berdasarkan status. Jika Anda memiliki status di tabel lain, Anda harus bergabung untuk mendapatkan info ini sehingga kinerja terganggu. Tentunya Anda harus memiliki status dalam tabel yang sama. Dan beri indeks! Anda masih dapat menggunakan bilangan bulat sebagai status, atau mungkin bidang enum.
sumber
Solusi yang benar adalah menggunakan Event Store / Source dengan CQRS atau blockchain. Masalah dengan menangkap peristiwa dalam RDB adalah bahwa RDB menyimpan snapshot dari satu peristiwa dalam waktu, dan hal-hal seperti "Status / Negara" adalah urutan mutasi yang berkembang dari waktu ke waktu.
sumber