SQL2005:联表多次表和保持裁判的完整性?
-
09-06-2019 - |
题
这是一个简化我的数据库:
Table: Property Fields: ID, Address Table: Quote Fields: ID, PropertyID, BespokeQuoteFields... Table: Job Fields: ID, PropertyID, BespokeJobFields...
然后我们还有其他表格相关的 报价 和 工作 表独立。
我现在需要加入 消息 表用户可以在这里记录电话信息离开过客户有关的工作和报价。
我可以创建两个相同的表(QuoteMessage 和 JobMessage),但这违反了干主要和看似混乱。
我可以创建一个 消息 表:
Table: Message Fields: ID, RelationID, RelationType, OtherFields...
但是这停止,我从使用限制强制执行我引用完整性。我还可以预见它会造成一些问题与发展侧使用皇宫SQL以后。
是有一个优雅的解决这个问题,或者我最终要破解的东西在一起吗?
烧伤
解决方案
创建一个消息表,包含一个独特的MessageId和各种性质需要保存一个消息。
Table: Message
Fields: Id, TimeReceived, MessageDetails, WhateverElse...
创建两个链接表-QuoteMessage和JobMessage.这些只包含两个领域的每一个,外键的报价/工作和信息。
Table: QuoteMessage
Fields: QuoteId, MessageId
Table: JobMessage
Fields: JobId, MessageId
在这种方式定义的数据属性信息在一个地方只有(使它容易的扩展,和查询所有信息),但你也有参照完整性的连接报价和作业的任何数量的消息。事实上,这两个报价和工作可以链接到 同 消息(我不知道如果这是适当的商业模式,但至少在数据模型使你的选择)。
其他提示
唯一其它的方式我能想到的是要有一个基消息表,这两个Id和一个TypeId.你的子表(QuoteMessage和JobMessage)随后的参考的基础表中的两MessageId和TypeId-但还检查限制对他们强制执行仅适当的MessageTypeId.
Table: Message
Fields: Id, MessageTypeId, Text, ...
Primary Key: Id, MessageTypeId
Unique: Id
Table: MessageType
Fields: Id, Name
Values: 1, "Quote" : 2, "Job"
Table: QuoteMessage
Fields: Id, MessageId, MessageTypeId, QuoteId
Constraints: MessageTypeId = 1
References: (MessageId, MessageTypeId) = (Message.Id, Message.MessageTypeId)
QuoteId = Quote.QuoteId
Table: JobMessage
Fields: Id, MessageId, MessageTypeId, JobId
Constraints: MessageTypeId = 2
References: (MessageId, MessageTypeId) = (Message.Id, Message.MessageTypeId)
JobId = Job.QuoteId
这是什么买你的,相比只是一个JobMesssage和QuoteMessage表?它提升了一个消息来第一类公民,这样就可以读取所有的信息从一个单一的表格。作为交换,查询路从一个消息给它的有关报价或职位是1个加入程。这取决于你的流程应用程序是否是一个很好的折衷,或没有。
至于2相同的表违反了干-我也不会获得挂了。在DB的设计,这是不干,以及更多关于规范化。如果这2件事,你模型具有同样的属性(列),但实际上却是不同的东西(表)-然后就是合理的,有多种表与类似的模式。更多相反的处理不同的东西合在一起。
@烧伤
Ian的答复(+1)是正确的 [见注].使用很多很多表 QUOTEMESSAGE
加入 QUOTE
要 MESSAGE
是最正确的模型,而是将留下的孤儿 MESSAGE
记录。
这是其中的一个 罕见的 的情况下触发可以使用。然而,需要谨慎应用,以确保一个单一的 MESSAGE
记录不能相关联的两个 QUOTE
和一个 JOB
.
create trigger quotemessage_trg
on quotemessage
for delete
as
begin
delete
from [message]
where [message].[msg_id] in
(select [msg_id] from Deleted);
end
注意到伊恩,我认为这是一个错误表的定义 JobMessage
, ,其中列应该 JobId, MessageId
(?).我会编辑的报价,但它可能要花我几年获得该级别的声誉!
为什么不只是两QuoteId和作业id领域中的消息表?或者有没有消息必须是关于一个报价或一个工作并不是两个?