Versi pendek
Saya harus menambahkan sejumlah properti tambahan ke setiap pasangan dalam banyak-ke-banyak bergabung. Melompati diagram di bawah ini, manakah dari Pilihan 1-4 yang merupakan cara terbaik, dalam hal kelebihan dan kekurangan, untuk mencapai ini dengan memperluas Base Case? Atau, adakah alternatif yang lebih baik yang belum saya pertimbangkan di sini?
Versi yang lebih panjang
Saat ini saya memiliki dua tabel dalam hubungan banyak-ke-banyak, melalui tabel gabungan antara. Sekarang saya perlu menambahkan tautan tambahan ke properti yang dimiliki oleh sepasang objek yang ada. Saya memiliki nomor tetap dari properti ini untuk setiap pasangan, meskipun satu entri dalam tabel properti mungkin berlaku untuk beberapa pasangan (atau bahkan dapat digunakan beberapa kali untuk satu pasangan). Saya mencoba menentukan cara terbaik untuk melakukan ini, dan saya mengalami kesulitan memilah bagaimana memikirkan situasi. Semantik sepertinya saya bisa menggambarkannya sebagai salah satu dari yang sama baiknya:
- Satu pasang tertaut ke satu set sejumlah properti tetap
- Satu pasang tertaut ke banyak properti tambahan
- Banyak (dua) objek yang ditautkan ke satu set properti
- Banyak objek yang terhubung ke banyak properti
Contoh
Saya memiliki dua jenis objek, X dan Y, masing-masing dengan ID unik, dan tabel penautan objx_objy
dengan kolom x_id
dan y_id
, yang bersama-sama membentuk kunci utama untuk tautan tersebut. Setiap X dapat dikaitkan dengan banyak Ys, dan sebaliknya. Ini adalah pengaturan untuk hubungan many-to-many saya yang sudah ada.
Kasus Dasar
Sekarang saya juga memiliki satu set properti yang didefinisikan dalam tabel lain, dan satu set kondisi di mana pasangan (X, Y) yang diberikan harus memiliki properti P. Jumlah kondisi ditetapkan, dan sama untuk semua pasangan. Mereka pada dasarnya mengatakan "Dalam situasi C1, pasangan (X1, Y1) memiliki properti P1", "Dalam situasi C2, pasangan (X1, Y1) memiliki properti P2", dan seterusnya, untuk tiga situasi / kondisi untuk setiap pasangan dalam gabungan meja.
Pilihan 1
Dalam situasi saya saat ini ada tepat tiga kondisi seperti itu, dan saya tidak memiliki alasan untuk berharap bahwa untuk meningkat, sehingga satu kemungkinan adalah dengan menambahkan kolom c1_p_id
, c2_p_id
dan c3_p_id
untuk featx_featy
, menentukan untuk diberikan x_id
dan y_id
, yang properti p_id
untuk penggunaan di masing-masing tiga kasus .
Ini sepertinya bukan ide yang bagus bagi saya, karena mempersulit SQL untuk memilih semua properti yang diterapkan pada fitur, dan tidak mudah mengubah ke kondisi yang lebih banyak. Namun, itu menegakkan persyaratan sejumlah kondisi tertentu per (X, Y) pasangan. Faktanya, ini adalah satu-satunya pilihan di sini yang melakukannya.
pilihan 2
Buat tabel kondisi cond
, dan tambahkan ID kondisi ke kunci utama tabel bergabung.
Satu kelemahan untuk ini adalah tidak menentukan jumlah kondisi untuk setiap pasangan. Lain adalah ketika saya hanya mempertimbangkan hubungan awal, dengan sesuatu seperti
SELECT objx.*, objy.* FROM objx
INNER JOIN objx_objy ON objx_objy.x_id = objx.id
INNER JOIN objy ON objy.id = objx_objy.y_id
Saya kemudian harus menambahkan DISTINCT
klausa untuk menghindari entri duplikat. Ini tampaknya telah kehilangan fakta bahwa setiap pasangan harus ada hanya sekali.
Opsi 3
Buat 'pasangan ID' baru di tabel bergabung, dan kemudian memiliki tabel tautan kedua antara yang pertama dan properti dan ketentuan.
Ini tampaknya memiliki kelemahan paling sedikit, selain dari kurangnya menegakkan sejumlah kondisi tetap untuk setiap pasangan. Apakah masuk akal untuk membuat ID baru yang mengidentifikasi tidak lain dari ID yang ada?
Opsi 4 (3b)
Pada dasarnya sama dengan Opsi 3, tetapi tanpa pembuatan bidang ID tambahan. Ini dilakukan dengan menempatkan kedua ID asli di tabel bergabung baru, sehingga berisi x_id
dan y_id
bidang, bukan xy_id
.
Keuntungan tambahan untuk formulir ini adalah tidak mengubah tabel yang ada (meskipun belum diproduksi). Namun, pada dasarnya duplikat seluruh tabel beberapa kali (atau terasa seperti itu), jadi juga tidak ideal.
Ringkasan
Perasaan saya adalah bahwa Pilihan 3 dan 4 cukup mirip sehingga saya bisa memilih salah satunya. Saya mungkin akan memiliki sekarang jika bukan untuk persyaratan sejumlah kecil, tetap tautan ke properti, yang membuat Opsi 1 tampak lebih masuk akal daripada yang seharusnya. Berdasarkan beberapa pengujian yang sangat terbatas, menambahkan DISTINCT
klausa ke pertanyaan saya tampaknya tidak mempengaruhi kinerja dalam situasi ini, tapi saya tidak yakin bahwa Opsi 2 mewakili situasi dan juga yang lain, karena duplikasi yang melekat yang disebabkan oleh penempatan pasangan (X, Y) yang sama berpasangan dalam beberapa baris pada tabel tautan.
Apakah salah satu dari opsi ini adalah cara terbaik saya ke depan, atau apakah ada struktur lain yang harus saya pertimbangkan?
sumber
DISTINCT
klausa, saya memikirkan pertanyaan seperti yang ada di akhir # 2, yang menghubungkanx
dany
melaluinyaxyc
tetapi tidak merujuk kec
... Jadi jika saya(x_id, y_id, c_id)
dibatasiUNIQUE
dengan baris(1,1,1)
dan(1,1,2)
, kemudianSELECT x.id, y.id FROM x JOIN xyc JOIN y
, saya akan mendapatkan kembali dua yang identik baris(1,1)
,, dan(1,1)
.Jawaban:
Pilihan 1
Itu tidak selalu mempersulit query SQL (lihat kesimpulan di bawah).
Ini berskala mudah ke lebih banyak kondisi, selama masih ada sejumlah kondisi, dan tidak ada lusinan atau ratusan.
Ya, dan meskipun Anda mengatakan dalam komentar bahwa ini "yang paling penting dari persyaratan saya", Anda belum mengatakan itu tidak masalah sama sekali.
pilihan 2Saya pikir Anda dapat mengabaikan opsi ini karena komplikasi yang Anda sebutkan. The
objx_objy
tabel mungkin meja mengemudi untuk beberapa pertanyaan Anda (misalnya "pilih semua properti diterapkan untuk fitur", yang saya mengambil berarti semua properti diterapkan padaobjx
atauobjy
). Anda dapat menggunakan tampilan untuk melakukan pra-penerapanDISTINCT
sehingga bukan masalah mempersulit kueri, tapi itu akan mengukur skala kinerja yang sangat buruk untuk keuntungan yang sangat sedikit.Opsi 3Tidak, tidak - Opsi 4 lebih baik dalam segala hal.
Opsi 4
Opsi ini baik-baik saja - ini adalah cara yang jelas mengatur hubungan jika jumlah properti variabel atau dapat berubah
Kesimpulan
Preferensi saya akan menjadi opsi 1 jika jumlah properti per
objx_objy
cenderung stabil, dan jika Anda tidak dapat membayangkan pernah menambahkan lebih dari beberapa tambahan. Ini juga satu-satunya opsi yang memberlakukan batasan 'jumlah properti = 3' - menegakkan batasan serupa pada opsi 4 kemungkinan akan melibatkan penambahanc1_p_id
... kolom ke tabel xy pula *.Jika Anda benar-benar tidak terlalu peduli dengan kondisi itu, dan Anda juga memiliki alasan untuk meragukan bahwa jumlah kondisi properti akan stabil, maka pilih opsi 4.
Jika Anda tidak yakin yang mana, pilih opsi 1 - itu lebih sederhana dan itu pasti lebih baik jika Anda memiliki pilihan, seperti yang dikatakan orang lain. Jika Anda menunda opsi 1 "... karena mempersulit SQL untuk memilih semua properti yang diterapkan ke fitur ..." Saya sarankan membuat tampilan untuk memberikan data yang sama dengan tabel tambahan dalam opsi 4:
tabel opsi 1:
lihat untuk 'meniru' opsi 4:
"pilih semua properti yang diterapkan ke fitur":
Aku di sini
sumber
Saya percaya salah satu dari opsi ini dapat bekerja, tetapi saya akan menggunakan opsi 1 jika jumlah kondisi benar-benar tetap pada 3, dan opsi 2 jika tidak. Pisau cukur Occam juga berfungsi untuk desain basis data, semua faktor lain yang setara dengan desain yang paling sederhana biasanya adalah yang terbaik.
Meskipun jika Anda ingin mengikuti aturan normalisasi basis data yang ketat, saya yakin Anda harus menggunakan 2 terlepas dari apakah jumlah kondisi sudah diperbaiki.
sumber