2017-01-13 5 views
0

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

В моем приложении я обрабатываю связь между пользователем и клиентом. У пользователей и клиентов может быть несколько адресов электронной почты. Кроме того, одновременно и пользователям, и клиентам могут быть назначены несколько разговоров. После того, как пользователь или клиент отправит сообщение электронной почты, система получает информацию об этом и создает сообщение об обмене сообщениями с базовой информацией об этом сообщении и электронной почтой с конкретными данными (тема, ОТ, ТО и т. Д.).

Database schema

Прямо сейчас, поля от и до только VARCHAR поля с адресами электронной почты. Я хотел бы изменить его так, чтобы поля FROM и TO были внешними ключами. Я планировал создать таблицу EmailAddresses, в которой будет храниться основная информация об адресах и таблицах UserEmailAddresses и ContactPersonEmailAddresses с конкретной информацией об адресе (например, хост, порт и т. Д.), Но я понял, что таблица EmailAddresses будет содержать только идентификатор. Это хороший подход? Я что-то упускаю?

Есть ли какие-либо лучшие решения для такого рода проблем?

Благодарим за помощь!

+0

Предположительно, таблица EmailAddresses имела бы адрес электронной почты в дополнение к ID-адресу справа? В этом подходе нет ничего плохого. Но нужен ли вам уровень нормализации?Ожидаете ли вы, что у нескольких пользователей есть тот же адрес электронной почты? Иногда это имеет смысл, но похоже, что это очень вероятно в отношении нормализации. –

+0

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

+0

@SeanLange Спасибо за ответ. В таблице EmailAddresses действительно может быть поле адреса, я забыл об этом. Однако я не вижу проблемы с нормализацией. Один пользователь может иметь несколько адресов электронной почты, но один адрес может быть назначен только одному пользователю (поле [Пользователь] в таблице UserEmailAddresses). –

ответ

1

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

Адрес электронной почты является юридическим лицом. Храните их в таблице. В любом месте необходим один адрес, поместите FK в одну таблицу адресов. Если несколько адресов являются или могут быть необходимы, поместите там таблицу пересечений.

create table EmailAddresses(
    ID  int auto_generating primary key, 
    Addr varchar not null unique, 
    Active bool 
); 

Являются ли такие поля, как Логин, Порт и т. Д., Действительно атрибутами адреса электронной почты? Может быть, вы сможете прояснить их, если хотите.

Тогда таблицы UserEmailAddresses и ContactEmailAddresses бы таблицы пересечений и выглядеть примерно так:

create table [User|Contact]EmailAddresses(
    UserID int not null references [Users|Contacts](ID)], 
    AddrID int not null references EmailAddresses(ID) 
); 

В сообщении электронной почты может иметь один только «С» значение, которое было бы в ряду EmailMessages, как это теперь, за исключением того, что теперь он может быть FK в одной таблице адресов. Сообщение может иметь один или несколько «до» значений так, что будет осуществляться также как пересечение таблица:

create table EmailTo(
    EmailID int not null references EmailMessages(ID)], 
    ToID  int not null references EmailAddresses(ID), 
    ToType enum(To, CC, BCC) 
); 

Есть, вероятно, другие требования, которые потребуют некоторых ограничения на некоторых или все из приведенных выше таблиц, но те, зависят по вашему использованию. Например, даже если приложения электронной почты позволяют одному и тому же адресу существовать более одного раза в списке From, вы можете захотеть поймать и ограничить такие вхождения. Это будет реализовано с помощью уникального ограничения на (EmailID, ToID)

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

+0

Благодарим за сообщение. Вход, порт и т. Д. - это поля, используемые для подключения к серверу электронной почты пользователя (IMAP). Таким образом, система имеет доступ (во время входа пользователя) к входящим сообщениям и т. Д. Я уже решил проблему, удалив отдельные таблицы электронной почты и создав одну таблицу, которая ссылается на таблицу «Персоны». Спасибо за идею нескольких полей, но я не думал об этом, и это очень хорошая идея. –

Смежные вопросы