我正在建立一个Mail数据库,MAIL
表的设计如下:
ID (Surrogate PK)
Recipient/Sender (Coming as FK from `REGISTERED_USERS` table - Recipient if outgoing mail and Sender if incoming mail)
Dispatch/Receive Date
Status (Coming as FK)
PostType (Whether it is Sent or Received mail)
问题
我的问题出在状态列中,因为传出或接收邮件的状态不同(例如,收到传入邮件的已接收邮件和已订购邮件,已盖章邮件,已转发邮件等)。
我的方法
我尝试过触发器来实现这一点,但我想确保使用一些约束条件有更好的解决方案/设计吗?非常感谢!
答案 0 :(得分:3)
这可能是基于意见但是......
您不应在同一列中存储不同的数据。您应该将所有传入/传出列拆分为两个,并仅为不同类型的邮件填充相关的列
在您的解决方案中,如果您在Recipient/Sender
列中有约翰,则在检查PostType
列之前,您不知道John是收件人或发件人。那不是很好的设计。每列应该是自我识别的。
我建议将您的设计更改为:
ID
Sender
Recipient
DispatchDate
ReceiveDate
IncomingStatus
OutgoingStatus
PostType
如果您真的需要组合数据来显示某个地方,您可以为此目的创建一个视图:
SELECT
CASE WHEN PostType = 1 THEN Sender ELSE Recipient END AS [Recipient/Sender]
CASE WHEN PostType = 1 THEN DispatchDate ELSE ReceiveDate END AS [Dispatch/Receive Date]
等。
(或将它们添加为计算列)
此外,通过分隔列,您可以为自己创建一个空间,例如,如果将来需要,也可以存储外发邮件的收件人。
答案 1 :(得分:1)
如果两种类型具有完全相同的属性,并且您可以通过添加StatusType属性或类似属性来区分它们,则可以将两种状态类型存储在一个表中。
如果OutgoingStatus的属性与IncomingStatus的属性不同,那么您应该考虑创建两个单独的表。
答案 2 :(得分:1)
执行此操作的一种方法是在Mail表上实现CHECK约束。
你可以像这样添加一个CHECK约束:
ALTER TABLE Mail
ADD CONSTRAINT CK_MAILSTATUS
CHECK ((PostType = 'Outgoing' AND [Status] IN('Ordered', 'Stamped', 'Dispatched')) OR (PostType = 'Incoming' AND [Status] IN('Received')))
之后,您将无法将记录插入到不符合CHECK约束条件的Mail表中。如果您尝试这样做,则会出错:
INSERT语句与CHECK约束冲突" CK_MAILSTATUS"。冲突发生在数据库" YourDatabase",table" dbo.Mail"。