sql为不同的表一个外键

时间:2017-01-13 21:42:17

标签: sql sql-server database foreign-keys

首先,我确实意识到有很多关于这个问题的问题,很有可能我已经知道其中一个答案,但是在我尝试过几个答案后,他们都没有工作我

在我的应用程序中,我处理用户和客户之间的通信。用户和客户都可以拥有多个电子邮件地址。此外,可以同时为用户和客户分配多个对话。在用户或客户发送电子邮件消息后,系统会接收有关该消息的信息,并创建一个ConversationMessage,其中包含有关消息的基本信息,以及具有特定数据(subject,FROM,TO等)的EmailMessage。

Database schema

现在,字段FROM和TO只是带有电子邮件地址的varchar字段。我想更改它,以便FROM和TO字段是外键。我打算创建一个EmailAddresses表来存储有关地址的基本信息,UserEmailAddresses和ContactPersonEmailAddresses表包含有关地址的特定信息(如主机,端口等),但我意识到EmailAddresses表只包含一个Id。这是一个好方法吗?我错过了什么吗?

对于这类问题有没有更好的解决方案?

感谢您的帮助!

1 个答案:

答案 0 :(得分: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。消息可能包含一个或多个" To"值,以便也可以作为交集表实现:

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

可能还有其他要求需要对上述任何或所有表进行一些约束,但这些要求取决于您的使用情况。例如,即使电子邮件应用程序允许在“发件人”列表中多次存在相同的地址,您也可能希望捕获并限制此类事件。这将通过(EmailID,ToID)

上的唯一约束来实现

可能的扩展是添加电子邮件列表,这些列表本身包含一组地址。这将需要EmailAddresses表进行拆分,但因为所有地址现在都位于一个表中,所以重新设计肯定会更容易将它们放在两个表中。