Jadi, sesuai jawaban Mehrdad untuk pertanyaan terkait , saya mengerti bahwa kolom tabel database yang "tepat" tidak menyimpan daftar. Sebaliknya, Anda harus membuat tabel lain yang secara efektif menampung elemen dari daftar tersebut dan kemudian menautkannya secara langsung atau melalui tabel persimpangan. Namun, jenis daftar yang ingin saya buat akan terdiri dari item unik (tidak seperti buah pertanyaan yang ditautkancontoh). Selanjutnya, item dalam daftar saya diurutkan secara eksplisit - yang berarti jika saya menyimpan elemen di tabel lain, saya harus mengurutkannya setiap kali saya mengaksesnya. Akhirnya, daftar ini pada dasarnya bersifat atomik karena kapan pun saya ingin mengakses daftar, saya ingin mengakses seluruh daftar daripada hanya sebagian - jadi tampaknya konyol untuk mengeluarkan kueri database untuk mengumpulkan potongan Daftar.
Solusi AKX (ditautkan di atas) adalah menyusun daftar dan menyimpannya dalam kolom biner. Tetapi ini juga tampaknya tidak nyaman karena itu berarti saya harus khawatir tentang serialisasi dan deserialisasi.
Apakah ada solusi yang lebih baik? Jika ada yang tidak ada solusi yang lebih baik, lalu mengapa? Tampaknya masalah ini harus muncul dari waktu ke waktu.
... hanya sedikit info lagi untuk memberi tahu Anda dari mana saya berasal. Begitu saya baru mulai memahami SQL dan database secara umum, saya beralih ke LINQ ke SQL, dan sekarang saya sedikit manja karena saya berharap dapat menangani model objek pemrograman saya tanpa harus memikirkan bagaimana objek dipertanyakan atau disimpan dalam database.
Terima kasih semuanya!
John
PEMBARUAN: Jadi dalam kebingungan pertama jawaban yang saya dapatkan, saya melihat "Anda bisa pergi ke rute CSV / XML ... tapi JANGAN!". Jadi sekarang saya sedang mencari penjelasan mengapa. Arahkan saya ke beberapa referensi yang bagus.
Juga, untuk memberi Anda gambaran yang lebih baik tentang apa yang saya lakukan: Dalam database saya, saya memiliki tabel Fungsi yang akan memiliki daftar pasangan (x, y). (Tabel juga akan memiliki informasi lain yang bukan merupakan konsekuensi untuk diskusi kita.) Saya tidak akan pernah perlu melihat bagian dari daftar pasangan (x, y). Sebaliknya, saya akan mengambil semuanya dan memplotnya di layar. Saya akan mengizinkan pengguna untuk menyeret node di sekitar untuk mengubah nilai sesekali atau menambahkan lebih banyak nilai ke plot.
Anda bisa melupakan semua SQL dan pergi dengan pendekatan "NoSQL". RavenDB , MongoDB , dan CouchDB muncul sebagai solusi yang mungkin. Dengan pendekatan NoSQL, Anda tidak menggunakan model relasional..Anda bahkan tidak dibatasi oleh skema.
sumber
Apa yang saya lihat banyak orang lakukan adalah ini (ini mungkin bukan pendekatan terbaik, perbaiki saya jika saya salah):
Tabel yang saya gunakan dalam contoh diberikan di bawah ini (tabel termasuk nama panggilan yang Anda berikan kepada pacar tertentu Anda. Setiap pacar memiliki id unik):
Misalkan, Anda ingin menyimpan banyak nama panggilan di bawah sebuah id. Inilah mengapa kami menyertakan
seq_no
bidang.Sekarang, isi nilai-nilai ini ke tabel Anda:
Jika Anda ingin menemukan semua nama yang telah Anda berikan kepada pacar Anda id 1 maka Anda dapat menggunakan:
sumber
Jawaban sederhana: Jika, dan hanya jika, Anda yakin bahwa daftar tersebut akan selalu digunakan sebagai daftar, maka gabungkan daftar itu bersama-sama di pihak Anda dengan karakter (seperti '\ 0') yang tidak akan digunakan di teks, dan simpan itu. Kemudian saat Anda mengambilnya, Anda dapat membaginya dengan '\ 0'. Tentu saja ada cara lain untuk melakukan hal ini, tetapi itu tergantung pada vendor database spesifik Anda.
Sebagai contoh, Anda dapat menyimpan JSON dalam database Postgres. Jika daftar Anda adalah teks, dan Anda hanya ingin daftar itu tanpa kerumitan lebih lanjut, itu kompromi yang masuk akal.
Orang lain telah mengajukan saran untuk membuat serialisasi, tetapi saya tidak benar-benar berpikir bahwa serialisasi adalah ide yang baik: Bagian dari hal yang rapi tentang database adalah bahwa beberapa program yang ditulis dalam bahasa yang berbeda dapat saling berkomunikasi. Dan program yang diserialkan menggunakan format Java tidak akan bekerja dengan baik jika program Lisp ingin memuatnya.
Jika Anda menginginkan cara yang baik untuk melakukan hal semacam ini biasanya ada tipe array-atau-serupa yang tersedia. Postgres misalnya, menawarkan array sebagai tipe, dan memungkinkan Anda menyimpan array teks, jika itu yang Anda inginkan , dan ada trik serupa untuk MySql dan MS SQL menggunakan JSON, dan DB2 IBM menawarkan tipe array juga (dalam memiliki dokumentasi yang bermanfaat ). Ini tidak akan umum jika tidak diperlukan.
Apa yang Anda kehilangan dengan menempuh jalan itu adalah gagasan tentang daftar sebagai sekumpulan hal secara berurutan. Setidaknya secara nominal, database memperlakukan bidang sebagai nilai tunggal. Tetapi jika hanya itu yang Anda inginkan, maka Anda harus melakukannya. Ini adalah penilaian nilai yang harus Anda buat sendiri.
sumber
Selain apa yang orang lain katakan, saya sarankan Anda menganalisis pendekatan Anda dalam jangka yang lebih panjang daripada sekarang. Saat ini kasus item itu unik. Saat ini kasus yang menggunakan item akan membutuhkan daftar baru. Hampir disyaratkan bahwa daftar saat ini pendek. Meskipun saya tidak memiliki domain spesifik, tidaklah sulit untuk berpikir bahwa persyaratan tersebut dapat berubah. Jika Anda membuat daftar serial Anda, Anda memanggang dalam ketidakfleksibelan yang tidak diperlukan dalam desain yang lebih dinormalisasi. Btw, itu tidak berarti hubungan Banyak: Banyak penuh. Anda bisa saja memiliki tabel anak tunggal dengan kunci asing untuk induk dan kolom karakter untuk item tersebut.
Jika Anda masih ingin melakukan serialisasi daftar ini, Anda mungkin mempertimbangkan untuk menyimpan daftar dalam XML. Beberapa database seperti SQL Server bahkan memiliki tipe data XML. Satu-satunya alasan saya menyarankan XML adalah karena hampir menurut definisi, daftar ini harus pendek. Jika daftarnya panjang, maka membuat serialisasi secara umum adalah pendekatan yang buruk. Jika Anda mengikuti rute CSV, Anda harus memperhitungkan nilai yang berisi pemisah yang berarti Anda harus menggunakan pengenal yang dikutip. Menganggap bahwa daftarnya pendek, mungkin tidak akan membuat banyak perbedaan apakah Anda menggunakan CSV atau XML.
sumber
Saya hanya akan menyimpannya sebagai CSV, jika nilainya sederhana maka itu harus menjadi semua yang Anda butuhkan (XML sangat bertele-tele dan serialisasi ke / dari itu mungkin akan berlebihan tetapi itu akan menjadi pilihan juga).
Berikut adalah jawaban yang bagus tentang cara mengeluarkan CSV dengan LINQ.
sumber
Jika Anda perlu membuat kueri pada daftar, simpan dalam tabel.
Jika Anda selalu menginginkan daftar tersebut, Anda dapat menyimpannya sebagai daftar yang dipisahkan dalam kolom. Bahkan dalam kasus ini, kecuali Anda memiliki alasan yang SANGAT spesifik untuk tidak melakukannya, simpanlah dalam tabel pencarian.
sumber
Hanya satu opsi yang tidak disebutkan dalam jawaban. Anda dapat menormalisasi desain DB Anda. Jadi, Anda membutuhkan dua tabel. Satu tabel berisi daftar yang benar, satu item per baris, tabel lain berisi seluruh daftar dalam satu kolom (dipisahkan koma, misalnya).
Ini dia desain DB 'tradisional':
Ini dia tabel yang dinormalisasi:
Idenya di sini - Anda memelihara tabel Daftar menggunakan pemicu atau kode aplikasi. Setiap kali Anda memodifikasi konten List_Item, baris yang sesuai dalam Daftar akan diperbarui secara otomatis. Jika Anda kebanyakan membaca daftar, itu bisa berfungsi dengan baik. Pro - Anda dapat membaca daftar dalam satu pernyataan. Kontra - pembaruan membutuhkan lebih banyak waktu dan upaya.
sumber
Jika Anda benar-benar ingin menyimpannya dalam kolom dan membuatnya dapat dikueri, banyak database yang mendukung XML sekarang. Jika tidak membuat kueri, Anda dapat menyimpannya sebagai nilai yang dipisahkan koma dan menguraikannya dengan fungsi saat Anda membutuhkannya untuk dipisahkan. Saya setuju dengan orang lain meskipun jika Anda ingin menggunakan database relasional, sebagian besar normalisasi adalah pemisahan data seperti itu. Saya tidak mengatakan bahwa semua data cocok dengan database relasional. Anda selalu dapat melihat jenis database lain jika banyak data Anda tidak sesuai dengan model.
sumber
Saya rasa dalam kasus tertentu, Anda dapat membuat "daftar" FAKE item di database, misalnya, barang dagangan memiliki beberapa gambar untuk menunjukkan detailnya, Anda dapat menggabungkan semua ID gambar yang dipisahkan dengan koma dan menyimpan string menjadi DB, maka Anda hanya perlu mengurai string saat Anda membutuhkannya. Saya sedang mengerjakan situs web sekarang dan saya berencana untuk menggunakan cara ini.
sumber
Saya sangat enggan untuk memilih jalan yang akhirnya saya putuskan untuk diambil karena banyak jawaban. Sementara mereka menambahkan lebih banyak pemahaman tentang apa itu SQL dan prinsip-prinsipnya, saya memutuskan untuk menjadi penjahat. Saya juga ragu untuk memposting temuan saya karena bagi beberapa orang lebih penting untuk melampiaskan rasa frustrasi kepada seseorang yang melanggar aturan daripada memahami bahwa hanya ada sedikit kebenaran universal.
Saya telah mengujinya secara ekstensif dan, dalam kasus khusus saya, itu jauh lebih efisien daripada menggunakan tipe array (dengan murah hati ditawarkan oleh PostgreSQL) atau menanyakan tabel lain.
Inilah jawaban saya: Saya telah berhasil menerapkan daftar ke dalam satu bidang di PostgreSQL, dengan menggunakan panjang tetap setiap item dari daftar. Katakanlah setiap item adalah warna sebagai nilai hex ARGB, itu berarti 8 karakter. Jadi, Anda dapat membuat larik berisi maksimal 10 item dengan mengalikan panjang setiap item:
Jika panjang item daftar Anda berbeda, Anda selalu dapat mengisi padding dengan \ 0
NB: Jelas ini belum tentu pendekatan terbaik untuk nomor hex karena daftar bilangan bulat akan mengkonsumsi lebih sedikit penyimpanan tetapi ini hanya untuk tujuan menggambarkan gagasan array ini dengan memanfaatkan panjang tetap yang dialokasikan untuk setiap item.
Alasan mengapa: 1 / Sangat nyaman: ambil item i di substring i * n, (i +1) * n. 2 / Tidak ada overhead kueri tabel silang. 3 / Lebih efisien dan hemat biaya di sisi server. Daftar ini seperti gumpalan mini yang harus dipisahkan oleh klien.
Sementara saya menghormati orang-orang yang mengikuti aturan, banyak penjelasan yang sangat teoritis dan sering gagal untuk mengakui bahwa, dalam beberapa kasus tertentu, terutama ketika bertujuan untuk mendapatkan biaya yang optimal dengan solusi latensi rendah, beberapa perubahan kecil lebih dari diterima.
"Tuhan melarang bahwa itu melanggar beberapa prinsip suci suci SQL": Mengadopsi pendekatan yang lebih berpikiran terbuka dan pragmatis sebelum melafalkan aturan selalu menjadi jalan yang harus ditempuh. Jika tidak, Anda mungkin akan berakhir seperti seorang fanatik yang jujur membacakan Tiga Hukum Robotika sebelum dilenyapkan oleh Skynet
Saya tidak berpura-pura bahwa solusi ini adalah terobosan, juga tidak ideal dalam hal keterbacaan dan fleksibilitas database, tetapi pasti dapat memberi Anda keunggulan dalam hal latensi.
sumber
Banyak database SQL memungkinkan tabel berisi subtabel sebagai komponen. Metode biasa adalah mengizinkan domain salah satu kolom menjadi tabel. Ini sebagai tambahan untuk menggunakan beberapa konvensi seperti CSV untuk menyandikan substruktur dengan cara yang tidak diketahui DBMS.
Ketika Ed Codd mengembangkan model relasional pada 1969-1970, dia secara spesifik mendefinisikan bentuk normal yang akan melarang jenis tabel bersarang ini. Bentuk normal kemudian disebut Bentuk Normal Pertama. Dia kemudian melanjutkan untuk menunjukkan bahwa untuk setiap database, ada database dalam bentuk normal pertama yang mengungkapkan informasi yang sama.
Mengapa repot-repot dengan ini? Nah, database dalam bentuk normal pertama mengizinkan akses kunci ke semua data. Jika Anda memberikan nama tabel, nilai kunci ke dalam tabel itu, dan nama kolom, database akan berisi paling banyak satu sel yang berisi satu item data.
Jika Anda memperbolehkan sel untuk memuat daftar atau tabel atau koleksi lainnya, sekarang Anda tidak dapat memberikan akses kunci ke sub item, tanpa mengerjakan ulang ide kunci sepenuhnya.
Akses kunci ke semua data sangat penting untuk model relasional. Tanpa konsep ini, model tidak relasional. Mengenai mengapa model relasional adalah ide yang bagus, dan apa yang mungkin menjadi batasan dari ide yang bagus itu, Anda harus melihat pengalaman terakumulasi selama 50 tahun dengan model relasional.
sumber
Anda dapat menyimpannya sebagai teks yang terlihat seperti daftar dan membuat fungsi yang dapat mengembalikan datanya sebagai daftar yang sebenarnya. contoh:
database:
Dan fungsi penyusun daftar (ditulis dengan python, tetapi seharusnya dapat dengan mudah diterjemahkan ke sebagian besar bahasa pemrograman lain). TEXT mewakili teks yang dimuat dari tabel sql. mengembalikan daftar string dari daftar yang berisi string. jika Anda ingin mengembalikan int sebagai ganti string, buat mode sama dengan 'int'. Begitu juga dengan 'string', 'bool', atau 'float'.
Juga di sini adalah fungsi daftar-ke-string jika Anda membutuhkannya.
sumber