Предполагая, что у меня есть несколько отношений в моей базе данных, например, Store, Employee и Sale, и я хочу соединить пары с помощью простого бинарного отношения. Лично я бы создал таблицы с именами Employee_Store и Employee_Sale с естественным ключом, состоящим из внешних ключей.
Теперь мой коллега настаивает на создании одной таблицы для нескольких отношений. Для приведенного выше примера может быть таблица с именем EmployeeLinks:
EmployeeLinks(
IdLink int PK,
IdEmployee int FK null,
IdStore int FK null,
IdSale int FK null,
LinkType int not null
)
Пожалуйста, помогите мне с вескими причинами, почему это не очень хорошая идея. У меня есть свои аргументы, но я хотел бы сохранить их в тайне и выслушать ваши объективные мнения.
РЕДАКТИРОВАТЬ:
Первоначально в таблице выше не было бы первичного ключа (!). Поскольку внешние ключи допускают нулевое значение, суррогатный ключ является единственным вариантом.
источник
Ответы:
Что ваш коллега предлагает в качестве первичного ключа для этой таблицы ссылок?
Конечно, столбцы первичного ключа не могут иметь значение NULL: таблица выше имеет значение NULL.
В приведенном выше примере нет естественного идентификатора строки (которым является PK) (столбец IDENTITY не является первичным ключом), поэтому он завершается неудачно в любом процессе моделирования. Даже не думайте о создании таблиц без какой-либо модели (ERD, ORM, IDEF1X и т. Д.)
Вам также понадобятся ограничения CHECK, чтобы убедиться, что у вас нет трехсторонних ссылок.
Наконец, вы отклоняетесь от 4-й и 5-й территории нормальной формы, но по неправильным причинам.
Я не могу найти никаких примеров в Интернете: это показывает, насколько это глупо
источник
I can't find any examples on the internet: that shows how stupid this is
Первая практическая причина, о которой я могу подумать, это производительность.
В «традиционной» модели вы можете иметь уникальный индекс
Idemployee, Idstore
или независимо от того, какие поля есть, и получить высокую производительность при поиске. Это также легко поддерживать для вкладышей. Уникальные индексы позволяют вам чаще объединять объединения, что может сделать оченьJOIN
быстро.В вашей примерной модели, чтобы получить достойную производительность, вам нужно иметь как минимум один индекс поля для каждого поля FK в таблице, в идеале - индекс покрытия для всех комбинаций, на которые будет ссылаться, то есть:
Я не уверен, что такое linktype, но если вы ссылаетесь на него, он, вероятно, должен быть проиндексирован.
Эти индексы необходимо будет поддерживать для каждой строки в таблице, независимо от того, заполнено это поле или нет. Вы можете добавить фильтр, но это тоже будет сложно с таким количеством комбинаций.
Это также усложнит вашу логику. Вам нужно будет либо выполнить поиск значения employeeid, найти строку с пустым значением хранилища и выполнить обновление; или просто вставьте новую строку для каждой новой ссылки, что противоречит цели объединения полей.
В основном вы будете использовать БОЛЬШЕ дискового пространства, иметь БОЛЬШЕ индексов для обслуживания и усложнять свою логику по существу без причины. Единственное «преимущество» - это меньшее количество таблиц, с которыми нужно иметь дело.
источник
Помещение нескольких связей в одну таблицу может быть полезно, если эти отношения имеют одинаковые атрибуты и / или если вы хотите агрегировать данные по нескольким отношениям.
Это необходимо, если типы отношений определяются пользователем во время выполнения. Однако это действительно редко так.
В вашем примере отношения не имеют общих атрибутов, отношения даже ссылаются на две разные таблицы. Это затрудняет применение ограничений, а дизайн также менее интуитивно понятен.
Я бы выбрал этот дизайн, только если создание таблиц буквально стоит денег.
источник