1

设计数据库时,两个表之间存在关系,即JobDocument。一个Job可以有多个Documents,但这些Documents中的一个(并且只有一个)需要标记为IsCurrent。这并不总是与Job相关的最新Document如何使用“是当前”要求实现一对多关系

在结构上,我可以看到两种方法。

第一种方法是将DocumentId列添加到Job,将JobId列添加到Document。这将起作用,但会创建一个循环引用:当导入到实体框架中时,最终会出现Job同时具有DocumentDocuments集合的特殊情况。同样,Document同时具有JobJobs集合。

第二种方法是在Document表中添加一个IsCurrent位标志。这将起作用,但是在逻辑上使作业具有多个IsCurrentDocuments,这是不允许的。

问题:

1)我是正确的思维有没有“第三条道路”摆脱这种困境的?

2)假设没有,哪个更好,为什么?我赞成第二个解决方案,因为它看起来更清洁,我们可以通过业务逻辑强制执行单个IsCurrent。我的同事主张以前的解决方案,因为它会导致更简单的C#代码和对象引用 - 如果我们重命名外键,它应该避免由Job/Jobs创建的混淆。

回答

3

如果你的后端是SQL Server,您可以创建一个filtered index以确保每个job最多有一个当前文档:

CREATE UNIQUE INDEX IX_Documents_Current 
    ON Documents (JobId) where IsCurrent=1 

这样一来,它不是只是在业务级别执行但是也在数据库内执行。

+0

太好了,谢谢。我认为过滤的索引是性能工具 - 我不知道它们可以用来强制执行完整性。 –

+0

@MattThrower - 如果你仔细想想,*任何*唯一索引至少在某些方面强制执行完整性。 –

+0

这么简单,如此优雅......明亮等等:总是阅读**所有**工具的使用文档。 – tschmit007

1

只是为了第三种方式(以及为了好玩):考虑使用不是一点,但是int在作业的文档中等于max + 1。

然后在{job FK,int表}上创建一个唯一索引。

,您可以:

  • 变化通过更新INT当前,
  • 获取当前通过搜索最大和
  • 防止由于具有唯一索引的一个以上的电流。
  • 通过对所述int使用min-1来创建新的非当前文档。

这不是最简单的实现。

0

是的,还有第三种解决这个难题的方法。您需要一个支持SQL CREATE ASSERTION的DBMS(并且当然支持它正确)。使用这样的DBMS,您可以声明适用于您的情况的任何数据规则,并且您的DBMS将为您执行该规则。

不幸的是,在SQL世界中不存在这样的DBMS *。在SQL世界之外,有这样的引擎。 ASSERTIONs是我的木马,我自己写了一个。如果你有兴趣,谷歌搜索应该很快引导你。

相关问题