Какие существуют альтернативы, когда для таблицы требуется слишком много внешних ключей?

8

У нас есть базовая таблица, которая определяет детали и содержит такую ​​информацию, как номер детали, описание, цена, вес и т. Д. У нас также есть приблизительно 400 таблиц, которые ссылаются на базовую таблицу и предоставляют дополнительную информацию о деталях на основе их типа / категории.

Мы начали с использования ограничений внешнего ключа, чтобы деталь не могла быть удалена из базовой таблицы, если на нее ссылаются в одной из 400 таблиц, специфичных для детали, но мы быстро достигли максимально 253 рекомендуемых внешних ключей для SQL Server 2005.

Существуют ли альтернативы внешним ключам в этой ситуации, которые обеспечат целостность данных? Мы не видели проблем с производительностью при доступе к данным, но обновление существующей детали в базовой таблице завершится неудачно, поскольку план запроса слишком сложен.

jellomonkey
источник
14
Вы действительно думаете, что вам нужно 400 отдельных таблиц? Насколько отличаются эти таблицы на самом деле? Я думаю, что вы пытаетесь исправить неправильную часть этого дизайна.
Аарон Бертран
2
Примерно сколько строк вы имеете дело с этой базой данных?
Джон Зигель
4
Я должен согласиться с Аароном Бертраном: если ваш дизайн требует от вас максимального использования внешних ключей, поддерживаемых сервером sql, возможно, пришло время подумать о редизайне.
DForck42
5
Я сделал много проектов в этой области - ценообразование, управление продуктом, спецификации продукта. Даже в сильно нормализованных проектах я никогда не приближался к такому количеству ФК на одном столе. Возможно, вы используете какую-то стратегию разделения данных (по клиенту или по времени или что-то в этом роде), которая заставила вас спроектировать этот путь? Трудно дать ответ без дополнительной информации о вашем дизайне и целях дизайна.
Карен Лопес
4
Не могли бы вы привести пример схемы, скажем, для 5 из этих таблиц ...
Дамир Сударевич

Ответы:

6

Если есть какой-либо способ группировки деталей, вы можете использовать промежуточные таблицы в качестве обходного пути. Это не сработает.

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

Но что-то в этом роде может.

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

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

Я хотел бы внимательно посмотреть на ваш DDL, прежде чем я порекомендую это сделать. И если вы сделаете это, не начинайте бросать идентификационные номера повсюду. Вы должны иметь возможность присоединять «Table 400» непосредственно к «Parts», не включая «GreenBlueIndigoViolet parts».

Майк Шеррилл 'Cat Recall'
источник
-4

Замените 400+ таблиц одной. Нужно только 3 поля (+1 автонумерация или любой первичный ключ, если хотите, не обязательно его иметь, вы можете сформировать его из других полей)

Значение атрибута идентификатора элемента

Итак, если в других ваших таблицах каждое поле представляет атрибут, в этой таблице все ваши атрибуты находятся в одном поле. Вы бы что-то вроде этого

Значение атрибута ItemID

Материал носка Шерсть

Цвет Носка Красный

Вес носка 20 фунтов

Чужая Планета Альфа Центавра

Чужой Цвет Фиолетовый

Инопланетянин Нет

ItemID, вероятно, должен быть числом / буквенно-цифровым символом ofc. Затем вы просто создаете кросс-таблицу с атрибутами как заголовки столбцов, когда это необходимо для создания таблиц, которые вам нравятся. Это также позволяет лучше запрашивать такие вещи, как «Покажите мне все предметы из Альфа Центавра», которые могут вернуть вам Чужого, а также фрагмент Метеорита, содержащий чуму, которая уничтожает человечество (оно приходит .....)

Оптимизация может быть сложной в зависимости от количества записей, но это гораздо лучший способ спроектировать это. Я сделал то же самое для базы данных, которая содержала кучу рецептов (10 000+), которые имели мало совпадений. Хорошо сработало в этом случае. На самом деле проблем со скоростью не было. Ваш может быть сложнее в зависимости от того, с кем вы имеете дело.

user2125055
источник
4
Это называется моделью значения атрибута сущности, и это, как правило, довольно ужасная идея по многим причинам. Для вашего примера сценария "альфа-центавра" вы, вероятно, посмотрите на 2 сканирования таблицы, и индексы использовать нельзя. Кроме того, он сводит на нет любые преимущества для типов данных, делает реляционные ограничения невозможными и, как правило, не оптимизируется и не масштабируется до какой-либо степени. Если вам нужно хранить более сотни таких строк, не делайте этого.
JNK
2
Как отмечает @JNK, обычно это не очень хорошее решение. И даже хуже, когда вы делаете это только с одним столом. Я бы сказал , что минимум 3 таблицы ( Entity, Entity_Attribute, Entity_Attribute_Value). Если вы хотите добавить полуадекватную обработку для различных типов данных и референтных ограничений, вам понадобится больше.
ypercubeᵀᴹ
1
В то время как OP может приближаться к некоторому пределу в традиционном нормированном дизайне из-за явной сложности объектов в их системе, большинство чрезвычайно сложных систем на самом деле не обрабатываются лучше в EAV, поскольку он предлагает гораздо более слабую поддержку типов и уровень приложений. ссылочная целостность, поскольку все данные хранятся достаточно обобщенно. EAV имеет свое полезное место, но я не был бы готов рекомендовать его в качестве ответа на эту проблему, как указано в настоящее время.
Кейд Ру
Да, каждый день узнавать что-то новое. Я самоучка, и это было что-то, что я придумал, чтобы решить проблему с рецептом, которая у меня была, которая звучит похоже на проблему парней. Ах хорошо. Спасибо за информацию об этом, я посмотрю в EAV, может быть, есть более чистый способ решить мою проблему. Может быть, это сработало для меня проще, так как все значения были одинакового типа данных. Я не знаю.
user2125055
2
@ user2125055 Это не проблема, и не принимайте никакую критику лично. Мы просто отвергаем идею использования EAV! Определенно есть случаи, когда это имеет смысл, но из-за недостатков вы должны быть очень осторожны с этим.
JNK