如何与" Is Current"实现一对多的关系。需求

时间:2015-06-03 15:51:48

标签: sql database entity-framework database-design relational-database

设计数据库时,两个表JobDocument之间存在关系。一个Job可以有多个Documents,但这些Documents中只有一个(只有一个)需要标记为IsCurrent。这并不总是与Document相关联的最新Job

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

第一个是向DocumentId添加Job列,向JobId添加Document列。这将起作用,但会创建一个循环引用:当导入到Entity Framework时,最终会出现Job同时拥有DocumentDocuments集合的特殊情况。同样地,Document同时包含JobJobs集合。

第二种是向IsCurrent表添加Document位标志。这可行,但在逻辑上可以让作业有多个IsCurrent Documents,这是不允许的。

问题:

1)我是否正确地认为没有"第三种方式"摆脱这种困境?

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

3 个答案:

答案 0 :(得分:3)

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

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

这样,它不是在业务级别强制执行,而是在数据库中强制执行。

答案 1 :(得分:1)

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

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

你可以:

  • 通过更新int来改变当前状态,
  • 通过搜索max和
  • 来获取当前值
  • 由于唯一索引而阻止有多个电流。
  • 使用min - 1为所述int。
  • 创建一个新的非当前文档

这不是最简单的实施方式。

答案 2 :(得分:1)

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

不幸的是,在SQL世界* 中没有这样的DBMS *。在SQL世界之外,有这样的引擎。 ASSERTIONs是我的木马,我自己写了一个。如果您有兴趣,Google搜索会引导您快速浏览。