Apa alternatif yang ada ketika sebuah meja membutuhkan terlalu banyak kunci asing?

8

Kami memiliki tabel dasar yang mendefinisikan bagian-bagian dan menyimpan informasi seperti nomor bagian, deskripsi, harga, berat, dll. Kami juga memiliki sekitar 400 tabel yang mereferensikan tabel dasar dan memberikan informasi tambahan tentang bagian-bagian berdasarkan jenis / kategorinya.

Kami mulai dengan menggunakan batasan kunci asing sehingga bagian tidak dapat dihapus dari tabel dasar jika direferensikan di salah satu dari 400 tabel bagian tertentu tetapi kami dengan cepat mencapai 253 kunci asing yang disarankan untuk SQL Server 2005.

Apakah ada alternatif selain kunci asing dalam situasi ini yang akan memastikan integritas data? Kami belum melihat masalah kinerja saat mengakses data tetapi memperbarui bagian yang ada di tabel dasar akan gagal karena rencana kueri terlalu rumit.

jellomonkey
sumber
14
Apakah Anda benar-benar berpikir Anda perlu 400 tabel khusus bagian? Betapa berbedanya masing-masing tabel ini, sungguh? Saya pikir Anda sedang mencoba untuk memperbaiki bagian yang salah dari desain ini.
Aaron Bertrand
2
Kira-kira berapa banyak baris yang Anda hadapi dalam database ini?
Jon Seigel
4
Saya harus setuju dengan Aaron Bertrand, jika desain Anda mengharuskan Anda untuk memaksimalkan dukungan kunci asing sql server, mungkin sudah saatnya mempertimbangkan desain ulang.
DForck42
5
Saya telah melakukan banyak desain di bidang ini - harga, manajemen produk, spesifikasi produk. Bahkan dalam desain yang sangat normal, saya tidak pernah mendekati banyak FK di meja yang sama. Apakah Anda mungkin melakukan semacam strategi partisi data (oleh klien atau waktu atau sesuatu seperti itu) yang menyebabkan Anda merancang ke arah ini? Sulit untuk memberikan jawaban tanpa lebih banyak informasi tentang desain dan tujuan desain Anda.
Karen Lopez
4
Bisakah Anda memberikan contoh skema untuk mengatakan 5 dari tabel ini ...
Damir Sudarevic

Jawaban:

6

Jika ada cara untuk mengelompokkan bagian, Anda mungkin bisa memperkenalkan tabel perantara sebagai solusi. Ini tidak akan berhasil.

Parts
+ Table 1
+ Table 2
+ ...
+ Table 400

Tetapi sesuatu di sepanjang garis ini mungkin.

Parts
+ RedOrangeYellow parts
  + Table 1
  + Table 2
  + ...
  + Table 200

+ GreenBlueIndigoViolet parts
  + Table 201
  + Table 202
  + ...
  + Table 400

Saya ingin melihat DDL Anda dengan saksama sebelum saya merekomendasikan ini. Dan jika Anda melakukan ini, jangan mulai melemparkan nomor ID di semua tempat. Anda harus dapat bergabung dengan "Tabel 400" langsung ke "Bagian" tanpa termasuk "Bagian GreenBlueIndigoViolet".

Mike Sherrill 'Cat Recall'
sumber
-4

Ganti 400+ tabel dengan satu. Hanya perlu 3 bidang (+1 autonumber atau kunci utama apa pun jika Anda menginginkannya, tidak harus memilikinya, Anda dapat mengeluarkannya dari bidang lain)

Item ID Nilai Atribut

Jadi di mana dalam tabel Anda yang lain, masing-masing bidang mewakili atribut, dalam tabel ini, atribut Anda semuanya dalam satu bidang. Anda akan memiliki sesuatu seperti ini

Nilai Atribut ItemID

Bahan Sock Wool

Warna Kaus Kaki Merah

Berat Kaus Kaki 20 pound

Alien Planet Alpha Centauri

Warna Alien Ungu

Alien Friendly No

ItemIDs mungkin harus berupa angka / alfanumerik. Kemudian, Anda hanya crosstab dengan Atrribut sebagai header kolom bila perlu untuk menghasilkan tabel seperti yang Anda suka. Ini juga memungkinkan untuk pertanyaan yang lebih baik untuk hal-hal seperti "Tunjukkan semua item yang berasal dari Alpha Centauri" yang dapat memberi Anda kembali Alien dan juga fragmen Meteorit yang berisi wabah yang menyapu umat manusia (datang .....)

Optimalisasi mungkin rumit tergantung pada berapa banyak catatan yang ada tetapi ini adalah cara yang jauh lebih baik untuk merancang ini. Saya melakukan hal yang sama untuk database yang berisi banyak resep (10k +) yang memiliki beberapa tumpang tindih. Bekerja dengan baik dalam hal itu. Benar-benar tidak memiliki masalah kecepatan. Milik Anda mungkin lebih sulit tergantung pada berapa banyak yang Anda hadapi.

pengguna2125055
sumber
4
Ini disebut model Nilai Atribut Entitas dan biasanya ini adalah ide yang sangat buruk karena banyak alasan. Sebagai contoh skenario "alpha centauri", Anda mungkin akan melihat 2 pemindaian tabel, dan indeks tidak dapat digunakan. Juga membatalkan setiap keuntungan untuk tipe data, membuat kendala relasional tidak mungkin, dan umumnya tidak dapat dioptimalkan atau terukur ke tingkat apa pun. Jika Anda perlu menyimpan lebih dari seratus baris seperti ini, jangan.
JNK
2
Seperti yang ditunjukkan oleh @JNK, biasanya bukan solusi yang baik. Dan lebih buruk lagi jika Anda melakukannya hanya dengan satu meja. Saya akan mengatakan minimum adalah 3 tabel ( Entity, Entity_Attribute, Entity_Attribute_Value). Jika Anda ingin menambahkan perlakuan semi-tepat untuk tipe data dan batasan referensial yang berbeda, Anda akan membutuhkan lebih banyak.
ypercubeᵀᴹ
1
Sementara OP mungkin mendekati semacam batasan dengan desain normalisasi tradisional karena kerumitan entitas dalam sistem mereka, sebagian besar sistem yang sangat kompleks tidak benar-benar ditangani dengan lebih baik di EAV, karena OP menawarkan jenis dukungan yang jauh lebih lemah dan tingkat aplikasi. integritas referensial karena semua data disimpan dengan cukup umum. EAV memiliki tempat yang bermanfaat, tetapi saya tidak akan siap untuk merekomendasikannya sebagai jawaban untuk masalah ini sebagaimana dinyatakan saat ini.
Cade Roux
Huh, pelajari sesuatu yang baru setiap hari. Saya otodidak dan itu adalah sesuatu yang saya temukan untuk menyelesaikan masalah resep yang saya alami, yang kedengarannya mirip dengan masalah orang ini. Baiklah Terima kasih atas informasinya, saya akan melihat ke EAV, mungkin ada cara yang lebih bersih untuk menyelesaikan masalah saya juga. Bisa jadi itu bekerja lebih mudah bagi saya karena semua nilai adalah datatype yang sama. Saya tidak tahu.
user2125055
2
@ user2125055 Tidak ada masalah, dan jangan anggap kritik secara pribadi. Kami hanya menolak ide menggunakan EAV! Jelas ada kasus penggunaan yang masuk akal, tetapi karena kekurangannya Anda harus sangat berhati-hati.
JNK