在SQL Server中设计条件数据库关系

时间:2010-01-21 21:03:23

标签: sql-server database database-design

我有三种基本类型的实体:人员,企业和资产。每个资产可以由一个且仅一个人或企业拥有。每个人和企业可以拥有0到多个资产。在Microsoft SQL Server中存储此类条件关系的最佳做法是什么?

我的初步计划是在Assets表中有两个可以为空的外键,一个用于People,一个用于Business。其中一个值将为null,而另一个将指向所有者。我在这种设置中看到的问题是它需要应用程序逻辑才能被解释和执行。这真的是最好的解决方案还是有其他选择?

7 个答案:

答案 0 :(得分:8)

答案 1 :(得分:2)

您不需要应用程序逻辑来强制执行此操作。最简单的方法是使用检查约束

(PeopleID is null and BusinessID is not null) or (PeopleID is not null and BusinessID is null)

答案 2 :(得分:1)

您可以拥有“人员和业务”“扩展”的其他实体。我们将此实体称为当前项目。个人和企业都有FK参加派对(是一种关系)。而资产可能还有一个FK派对(属于关系)。

话虽如此,如果将来资产可以由多个实例共享,最好创建m:n关系,它可以提供灵活性,但会使应用程序逻辑和查询复杂化。

答案 3 :(得分:1)

ErikE's answer给出了关于如何在表中进行超类型/子类型关系的一个很好的解释,很可能是我在你的情况下要做的,但是,它并没有真正解决这个问题你提出的也很有趣,即:

  1. 在Microsoft SQL Server中存储此类条件关系的最佳做法是什么?
  2. ...还有其他选择吗?
  3. 对于那些我推荐this blog entry on TechTarget的摘录摘录自Eric Johnson和Joshua Jones的“SQL Server数据建模指南,涵盖SQL Server 2005和2008”,其中有3个可能的选项。< / p>

    总之,它们是:

    1. 超类型表 - 几乎与您提议的内容相匹配,有一个表格,其中一些字段在其他字段填充时始终为空。只有几个字段不共享时很好。因此,根据业务和人员的不同,您可以将它们组合到一个表中,可能是Owners,然后在Asset表中只有OwnerID。
    2. 子类型表 - 基本上与Supertype表相反,是您现在所拥有的。这里我们有很多独特的字段,也许一两个相同,所以我们只需要在每个表中显示重复的字段。你发现这并不适合你的情况。
    3. 超类型和子类型表 - 上述两者的组合,其中匹配字段放在单个表中,而单独的表中的唯一字符和匹配的ID用于从一个表中连接记录表到另一个。这符合ErikE提出的解决方案,如上所述,也是我赞成的解决方案。
    4. 可悲的是,它没有继续解释哪个(如果有的话)是最佳做法,但对于了解那里的选项肯定是一个很好的阅读。

答案 4 :(得分:0)

你可以用触发器强制执行逻辑。然后,无论记录如何更改,只会填写其中一个文件。

您还可以拥有一个PeopleAsset表和一个BusinessAsset表,但仍然会遇到强制执行的问题,即只有其中一个表有记录。

答案 5 :(得分:0)

资产将拥有拥有者的外键,您应该设置一个关联表来链接资产和业务。如其他注释中所述,您可以使用触发器和/或约束来确保数据保持一致状态。即。删除业务时,请删除关联表中的行。

答案 6 :(得分:0)

表人,企业都可以将UUID用作主键,并且可以将两者合并到视图中以实现sql连接。

因此,由于UUID几乎是唯一的,因此您可以在与人和企业有关的“资产”关系中仅使用一个外键列。您可以像这样简单地查询:

select * from Assets
join view_People_Businesses as v on v.id = Assets.fk