Соединительная таблица и вопрос нормализации - PullRequest
0 голосов
/ 03 июля 2011

Я с трудом пытаюсь выяснить, приемлем ли следующий шаблон проектирования.У меня есть следующие требования (и некоторые другие) для реляционной модели:

1) Она должна быть в состоянии представлять приложения (такие как AppA, AppB, AppC), каждое из которых имеетэто собственный набор атрибутов.

2) Каждое приложение может общаться через разные каналы, такие как Internet (электронная почта, Twitter, Facebook), Phone (SMS, MMS и т. д.), так что естьотношения «многие ко многим» между программами и каналами.

3) Существует набор предопределенных идентификаторов (адреса, номера телефонов, учетные записи для входа в систему), которые могут совместно использоваться многими программами, поэтому сновамежду программами и идентификаторами существует отношение многие ко многим.

4) Один и тот же идентификатор может отправлять сообщения нескольких типов, как и программы (опять же, многие ко многим), но мне нужночтобы иметь возможность ограничивать использование идентификаторов для типа связи для каждого приложения.

По сути, я создал четыре таблицы: Program, Channel, Ident и CommunicationTypeхранить информацию окаждый из них, и вместо создания таблиц соединений для (Program, Channel), (Program, Identifier) и т. д., которые могли бы просто усложнить проект, я создал одну таблицу, состоящую из первичных ключей этих четырех таблиц, с уникальным ограничением на (Program, Channel, Ident, CommunicationType).Теперь каждая запись этой таблицы связана с данным сообщением.

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

Ответы [ 3 ]

1 голос
/ 03 июля 2011

я бы этого не делал.

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

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

1 голос
/ 03 июля 2011

По сути, я создал четыре таблицы: Program, Channel, Ident и CommunicationType для хранения информации о каждой из них, и

Это хорошая идея.

вместо создания таблиц соединений для (Программа, Канал), (Программа, Идентификатор) и т. Д., Которые могут просто усложнить проектирование, я создал одну таблицу, состоящую из первичных ключей этих четырех таблиц суникальное ограничение для (Program, Channel, Ident, CommunicationType).

При разработке таблиц, подобных этой, нужно быть осторожным с одной вещью.Ваша структура, которая имеет ключ {Program, Channel, Ident, CommunicationType}, допускает любую возможную комбинацию Program и Channel, Channel и Ident, Program и CommunicationType и так далее.Иногда это плохая идея.

Один и тот же идентификатор может отправлять несколько типов сообщений, как и программы (опять же, многие ко многим), но я должен иметь возможность ограничить использованиеидентификаторы для типа связи для каждого приложения.

И это делает его плохой идеей.Похоже, вы говорите, что не каждая комбинация Ident, Program и CommunicationsType действительна.

Храните действительные комбинации в своих таблицах.Используйте ссылки на внешний ключ для поддержания целостности данных.

Создайте таблицу с ключом {Program, Ident, CommunicationsType}.Таблица с ключом {Program, Channel, Ident, CommunicationType} может установить ссылку на внешний ключ.

Построить столько таблиц, сколько потребуется для реализации всех известных вам ограничений.Больше таблиц означает, что проверки целостности данных проще.(Вам может понадобиться больше таблиц, чем я упомянул. Не думайте, что им нужно иметь два столбца; им может понадобиться больше.)

Совершенно не ясно, что вам нужна таблица с ключами {Program, Channel}.Но если вы это сделаете, то вам нужно что-то построить таблицы в этом направлении.(Воздушный код.)

create table pc (
    program_name varchar(10) not null references programs (program_name),
    channel_name varchar(10) not null references channels (channel_name),
    primary key (program_name, channel_name)
);

create table pict (
    program_name varchar(10) not null,
    channel_name varchar(10) not null,
    comm_type varchar(10) not null references communication_type (comm_type),
    primary key (program_name, channel_name, comm_type),
    foreign key (program_name, channel_name) 
        references pc (program_name, channel_name) 
);

create table your-table-name (
    program_name varchar(10) not null,
    channel_name varchar(10) not null,
    comm_type varchar(10) not null,
    ident varchar(10) not null,
    primary key (program_name, channel_name, comm_type, ident),
    foreign key (program_name, channel_name, comm_type) 
        references pict (program_name, channel_name, comm_type),
    foreign key (ident) references ident (ident)
);

При необходимости добавьте другие столбцы.В некоторых случаях вы, вероятно, обнаружите, что вам нужны перекрывающиеся внешние ключи.Я не думаю, что они вам нужны здесь, но я могу ошибаться.

Я не уверен, что вы подразумеваете под "если это наносит ущерб принципам нормализации".Таблица с первичным ключом из четырех столбцов не нарушает ни одной из нормальных форм только по этой причине , хотя может и по другим причинам.Неспособность реализовать все известные ограничения - это, как правило, неоптимальный дизайн, но не потому, что он нарушает любую из нормальных форм.

1 голос
/ 03 июля 2011

Извините за предоставление вам ответа, который запрашивает дополнительную информацию.Моя репутация на данный момент не позволяет комментировать ...

Я не вижу ничего плохого в выбранном дизайне на основе объяснения.

Однако, чтобы действительно ответить на ваш вопрос, было бы полезно понятьпочему вы выбрали этот дизайн.

В конце концов он также будет работать без единой таблицы со всеми ключами и составного уникального индекса.Весьма ограниченным образом блокировать все комбинации таким образом.

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

Почему вы хотите, чтобы каждый уникальный канал связи хранился таким образом?

...