Cara menyimpan status catatan (seperti tertunda, lengkap, konsep, dibatalkan ...)

18

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.

  1. Tabel Posting memiliki bidang teks yang menyertakan teks status.
  2. 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

veganista
sumber
Apa yang Anda maksud dengan "kapan saja"? Apakah itu berarti sebagai bagian dari aktivitas pengguna, atau sebagai bagian dari siklus rilis perangkat lunak?
kevin cline
Keduanya, dalam hal mana salah satu pendekatan yang disebutkan di sini paling baik digunakan. Jadi jika pengguna dapat menambahkan status baru, atau jika yang baru ditambahkan pada titik selanjutnya dalam proyek
veganista
Menyimpan teks dalam database mungkin merupakan denormalisasi yang baik. Saya pikir itu mungkin tergantung pada detail yang tepat misalnya Seberapa sering organisasi Anda mengubah prosesnya (mengarah ke kemungkinan perubahan status)?
Jaydee
Jika pengguna dapat menambahkan status baru, maka itu hal yang sama sekali berbeda. Anda mungkin ingin merekam pengguna yang membuat dll dengan status dan pasti akan membutuhkan tabel lain.
kevin cline

Jawaban:

14

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.

kevin cline
sumber
1
+1, Kecuali kebutuhan khusus untuk menyimpan daftar status di db, ini umumnya cara paling sederhana, paling tidak rumit untuk melakukannya.
GrandmasterB
2
Ini tidak masalah, kecuali jika Anda mulai mengubah arsitektur status atau menyimpan tanggal mutasi
LastTribunal
10

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

select * from myrecords where status < Status.Complete;
pengguna281377
sumber
Beberapa orang idiot juga bisa menghapus ID.
Morons
Keuntungan lain dari ID adalah Anda harus menyediakan pelokalan. Anda dapat menggunakan ID Anda untuk mencari string sumber daya dan menampilkan. Dengan string kode keras ini tidak mungkin
armitage
3
Saya tidak berpikir melakukan status menggunakan perbandingan "lebih besar dari" atau "lebih kecil dari" seperti yang Anda tunjukkan adalah ide yang bagus. Ini mungkin bekerja untuk aplikasi yang lebih sederhana seperti contoh ini tetapi tidak baik untuk aplikasi yang lebih kompleks (walaupun saya yakin Anda menyadarinya)
veganista
1
@armitage: sangat mungkin untuk melakukan pencarian menggunakan string. Nama sumber daya adalah string:status.draft=Draught
kevin cline
veganista: Tentu, mungkin ada kesulitan dengan perbandingan lebih besar dari / lebih kecil dari, tetapi saya telah melihat sistem besar dan rumit yang melakukan itu dan hidup.
user281377
4

Tiga aturan basis data relasional:

  1. Normalisasi
  2. Normalisasi
  3. Normalisasi

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.

Spencer Rathbun
sumber
Alasan yang Anda nyatakan di sini adalah alasan tepatnya saya menggunakan meja lain untuk menyimpan staus saya. Alasan utama mengapa saya mengajukan pertanyaan ini adalah untuk melihat apakah kadang-kadang ada baiknya menggunakan bidang teks yang lebih sederhana.
veganista
@Liam Hanya jika itu menjadi normal ke bidang teks. Yaitu, jika bidang teks Anda hanya bergantung pada kunci utama, dan Anda mencari sesuatu berdasarkan kunci utama , dengan bidang teks yang datang. DB relasional adalah tentang hubungan, Anda memilikinya di sini, jadi itu perlu didefinisikan. Salah satu dari beberapa pengecualian adalah jika Anda menangani data kotor dari sumber luar, dan Anda tidak punya waktu untuk memodelkannya sepenuhnya. Hindari ini jika memungkinkan.
Spencer Rathbun
menyembunyikan mata, berduka dengan GUID yang tidak akan pernah kembali
sq33G
Anda seharusnya menulis "tiga teori database relasional". Teori tidak selalu praktis. Seringkali lebih efisien untuk menyimpan kode status secara langsung dalam catatan yang terkait. Jika Anda tidak perlu mencarinya untuk menggunakannya, menghapus gabungan ke tabel lain menghemat banyak pemrosesan yang terbuang.
Suncat2000
Turun karena informasi yang salah tentang jenis kolom vs pemindaian tabel penuh.
igorrs
3

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.

Tuan Spark
sumber
1

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.

Dibbeke
sumber
0

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.

smp7d
sumber
Jika Anda tidak mengkhawatirkan kinerja, Anda kemungkinan mengorbankan skalabilitas. Tidak mungkin bagi komputer untuk menghindari status magis: 0 dan 1 secara intrinsik magis.
Suncat2000
0

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).

ElGringoGrande
sumber
-1

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.

dxvargas
sumber
-2

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.

LastTribunal
sumber
Jika Anda akan memilih suara posting saya, maka buat kasus. Jika tidak, Anda hanya lemming yang berpikiran lembut yang memiliki ruang lingkup sangat sedikit di luar kotak
LastTribunal