Bayangkan formulir web dengan satu set kotak centang (salah satu atau semuanya dapat dipilih). Saya memilih untuk menyimpannya dalam daftar nilai yang dipisahkan koma yang disimpan dalam satu kolom dari tabel database.
Sekarang, saya tahu bahwa solusi yang tepat adalah membuat tabel kedua dan menormalkan database dengan benar. Itu lebih cepat untuk mengimplementasikan solusi yang mudah, dan saya ingin memiliki bukti konsep aplikasi itu dengan cepat dan tanpa harus menghabiskan terlalu banyak waktu untuk itu.
Saya pikir waktu yang dihemat dan kode yang lebih sederhana sepadan dengan situasi saya, apakah ini pilihan desain yang dapat dipertahankan, atau haruskah saya menormalkannya dari awal?
Lebih banyak konteks, ini adalah aplikasi internal kecil yang pada dasarnya menggantikan file Excel yang disimpan pada folder bersama. Saya juga bertanya karena saya sedang berpikir untuk membersihkan program dan membuatnya lebih bisa dikelola. Ada beberapa hal di sana yang tidak sepenuhnya saya sukai, salah satunya adalah topik dari pertanyaan ini.
sumber
Jawaban:
Selain melanggar Formulir Normal Pertama karena kelompok nilai berulang yang disimpan dalam satu kolom, daftar yang dipisahkan koma memiliki banyak masalah lain yang lebih praktis:
idlist REGEXP '[[:<:]]2[[:>:]]'
*Untuk mengatasi masalah ini, Anda harus menulis banyak kode aplikasi, menemukan kembali fungsionalitas yang sudah disediakan RDBMS jauh lebih efisien .
Daftar yang dipisahkan oleh koma cukup salah sehingga saya membuat bab pertama dalam buku saya: SQL Antipatterns: Menghindari Jebakan Pemrograman Basis Data .
Ada saat-saat ketika Anda perlu melakukan denasionalisasi , tetapi seperti yang disebutkan oleh @OMG Ponies , ini adalah kasus pengecualian. “Optimalisasi” non-relasional apa pun menguntungkan satu jenis kueri dengan mengorbankan penggunaan data lainnya, jadi pastikan Anda tahu mana dari kueri Anda yang perlu diperlakukan secara khusus sehingga layak dinasionalisasi.
* MySQL 8.0 tidak lagi mendukung sintaks ekspresi kata-batas ini.
sumber
"Salah satu alasannya adalah kemalasan".
Ini membunyikan bel alarm. Satu-satunya alasan Anda harus melakukan sesuatu seperti ini adalah karena Anda tahu bagaimana melakukannya "dengan cara yang benar" tetapi Anda sampai pada kesimpulan bahwa ada alasan nyata untuk tidak melakukannya dengan cara itu.
Setelah mengatakan ini: jika data yang Anda pilih untuk disimpan dengan cara ini adalah data yang Anda tidak akan pernah perlu bertanya, maka mungkin ada kasus untuk menyimpannya dengan cara yang Anda pilih.
(Beberapa pengguna akan membantah pernyataan di paragraf saya sebelumnya, dengan mengatakan bahwa "Anda tidak akan pernah tahu persyaratan apa yang akan ditambahkan di masa depan." Pengguna ini salah arah atau menyatakan keyakinan agama. Kadang-kadang menguntungkan untuk bekerja dengan persyaratan yang Anda inginkan. miliki sebelum Anda.)
sumber
Ada banyak pertanyaan pada SO yang bertanya:
Masalah lain dengan daftar yang dipisahkan koma adalah memastikan nilainya konsisten - menyimpan teks berarti kemungkinan kesalahan ketik ...
Ini semua adalah gejala dari data yang didenormalisasi, dan menyoroti mengapa Anda harus selalu membuat model untuk data yang dinormalisasi. Denormalisasi dapat menjadi optimasi permintaan, untuk diterapkan ketika kebutuhan benar-benar muncul dengan sendirinya .
sumber
Secara umum apa pun bisa dipertahankan jika memenuhi persyaratan proyek Anda. Ini tidak berarti bahwa orang akan setuju atau ingin mempertahankan keputusan Anda ...
Secara umum, menyimpan data dengan cara ini tidak optimal (mis. Lebih sulit untuk melakukan kueri yang efisien) dan dapat menyebabkan masalah pemeliharaan jika Anda memodifikasi item dalam formulir Anda. Mungkin Anda bisa menemukan jalan tengah dan menggunakan integer yang mewakili satu set flag bit sebagai gantinya?
sumber
Ya, saya akan mengatakan bahwa itu benar-benar buruk. Itu pilihan yang bisa dipertahankan, tetapi itu tidak membuatnya benar atau baik.
Ini merusak bentuk normal pertama.
Kritik kedua adalah bahwa menempatkan hasil input mentah langsung ke dalam database, tanpa validasi atau mengikat sama sekali, membuat Anda terbuka untuk serangan injeksi SQL.
Apa yang Anda sebut kemalasan dan kurangnya pengetahuan SQL adalah hal-hal yang membuat orang baru. Saya akan merekomendasikan meluangkan waktu untuk melakukannya dengan benar dan melihatnya sebagai kesempatan untuk belajar.
Atau biarkan apa adanya dan pelajari pelajaran menyakitkan dari serangan injeksi SQL.
sumber
Yah saya telah menggunakan daftar pasangan kunci / nilai tab dipisahkan dalam kolom NTEXT di SQL Server selama lebih dari 4 tahun sekarang dan berfungsi. Anda kehilangan fleksibilitas membuat kueri tetapi di sisi lain, jika Anda memiliki perpustakaan yang tetap / derpersists pasangan nilai kunci maka itu bukan ide yang buruk.
sumber
Saya membutuhkan kolom multi-nilai, itu bisa diimplementasikan sebagai bidang xml
Itu dapat dikonversi menjadi koma yang dibatasi seperlunya
meminta daftar XML dalam server sql menggunakan Xquery .
Dengan menjadi bidang xml, beberapa masalah dapat diatasi.
Dengan CSV: Tidak dapat memastikan bahwa setiap nilai adalah tipe data yang benar: tidak ada cara untuk mencegah 1,2,3, pisang, 5
Dengan XML: nilai dalam tag dapat dipaksa menjadi jenis yang benar
Dengan CSV: Tidak dapat menggunakan batasan kunci asing untuk menautkan nilai ke tabel pencarian; tidak ada cara untuk menegakkan integritas referensial.
Dengan XML: masih menjadi masalah
Dengan CSV: Tidak dapat menegakkan keunikan: tidak ada cara untuk mencegah 1,2,3,3,3,5
Dengan XML: masih menjadi masalah
Dengan CSV: Tidak dapat menghapus nilai dari daftar tanpa mengambil seluruh daftar.
Dengan XML: item tunggal dapat dihapus
Dengan CSV: Sulit untuk mencari semua entitas dengan nilai yang diberikan dalam daftar; Anda harus menggunakan pemindaian tabel yang tidak efisien.
Dengan XML: bidang xml dapat diindeks
Dengan CSV: Sulit untuk menghitung elemen dalam daftar, atau melakukan kueri agregat lainnya. **
Dengan XML: tidak terlalu sulit
Dengan CSV: Sulit untuk menggabungkan nilai ke tabel pencarian yang dirujuk. **
Dengan XML: tidak terlalu sulit
Dengan CSV: Sulit untuk mengambil daftar dalam urutan yang diurutkan.
Dengan XML: tidak terlalu sulit
Dengan CSV: Menyimpan bilangan bulat sebagai string membutuhkan ruang sekitar dua kali lebih banyak daripada menyimpan bilangan bulat biner.
Dengan XML: penyimpanan bahkan lebih buruk daripada csv
Dengan CSV: Ditambah banyak karakter koma.
Dengan XML: tag digunakan sebagai ganti koma
Singkatnya, menggunakan XML mengatasi beberapa masalah dengan daftar yang dibatasi DAN dapat dikonversi ke daftar yang dibatasi sesuai kebutuhan
sumber
Ya, itu adalah yang buruk. Pandangan saya adalah bahwa jika Anda tidak suka menggunakan database relasional kemudian mencari alternatif yang cocok untuk Anda, ada banyak proyek "NOSQL" yang menarik di luar sana dengan beberapa fitur yang sangat canggih.
sumber
Saya mungkin akan mengambil jalan tengah: membuat setiap bidang di CSV menjadi kolom terpisah dalam database, tetapi tidak terlalu khawatir tentang normalisasi (setidaknya untuk saat ini). Pada titik tertentu, normalisasi mungkin menjadi menarik, tetapi dengan semua data dimasukkan ke dalam satu kolom, Anda hampir tidak mendapat manfaat dari menggunakan database sama sekali. Anda perlu memisahkan data menjadi bidang / kolom logis / apa pun yang ingin Anda panggil sebelum dapat memanipulasinya secara bermakna.
sumber
Jika Anda memiliki jumlah bidang boolean yang tetap, Anda bisa menggunakan
INT(1) NOT NULL
(atauBIT NOT NULL
jika ada) atauCHAR (0)
(nullable) untuk masing-masing. Anda juga bisa menggunakanSET
(saya lupa sintaks yang tepat).sumber
INT(1)
membutuhkan 4 byte; yang(1)
tidak berarti.