如何在SQL Server中建模互斥关系

时间:2010-04-24 13:43:47

标签: sql sql-server database-design

我必须为现有应用程序添加功能,并且我遇到了数据情况,我不确定如何建模。我被限制为创建新的表和代码。如果我需要改变现有的结构,我认为我的客户可能会拒绝该提议。虽然如果它是唯一能够做到正确的方法,那么我将不得不这样做。

我有一个Item表,可以链接到任意数量的表,这些表可能会随着时间的推移而增加。该项只能链接到另一个表,但另一个表中的记录可能有很多项链接到它。

链接到的表/实体的示例包括PersonVehicleBuildingOffice。这些都是单独的表格。

项目示例包括PenStaplerCushionTyreA4 PaperPlastic BagPoster,{ {1}}

例如,可以将Decoration"分配给PosterPersonOffice。将来,如果他们添加Building表,也可以将其添加到该表中。

我的初步想法是:

Conference Room

Item { ID, Name } LinkedItem { ItemID, LinkedToTableName, LinkedToID } 字段将允许我在我的代码中标识要链接到的正确表。

我对这个解决方案并不是很满意,但我不能想到其他任何事情。请帮忙! :)

谢谢!

3 个答案:

答案 0 :(得分:12)

将表名存储为列值不是一个好习惯。这是一个糟糕的黑客。

有两种标准方法可以完成您要做的事情。第一种称为单表继承。 ORM工具很容易理解这一点,但会进行一些规范化。我们的想法是,所有这些实体 - PersonVehicle,无论如何 - 都存储在同一个表中,每个条目通常有几个未使用的列,以及鉴别器标识实体的类型的字段。

discriminator字段通常是整数类型,映射到代码中的某个枚举。它也可能是数据库中某些查找表的外键,用于标识哪些数字对应于哪些类型(表名,只是描述)。

另一种方法是多表继承,这对您的数据库更好,但不容易在代码中映射。你可以通过一个基表来定义所有对象的一些常见属性 - 可能只是一个ID和一个名称 - 以及所有“特定”表(Person等)。使用基本ID作为唯一外键(通常也是主键)。

在第一种情况下,排他性是隐含的,因为所有实体都在一个表中。在第二种情况下,关系在Item base 实体ID之间,这也保证了唯一性。

请注意,对于多表继承,您有一个不同的问题 - 您不能保证只有一个继承表使用基本ID。它可以被几个使用,或根本不使用。这就是为什么多表继承方案通常也有一个鉴别器列,以识别哪个表是“预期的”。同样,此鉴别器不包含表名,它包含一个查找值,消费者可以(或可能不)使用该查找值来确定要加入哪个其他表。

多表继承与您当前的架构更接近,所以我建议使用它,除非您需要将它与Linq to SQL或类似的ORM一起使用。

请参阅此处以获取详细的详细教程:Implementing Table Inheritance in SQL Server

答案 1 :(得分:9)

查找车辆构建 Office 的常见内容。由于缺乏更好的术语,我使用了实体。然后在 Entity 及其子类型之间实现超类型/子类型关系。请注意,EntityID在所有子类型表中都是PKFK。现在,您可以将表链接到实体(所有者)。 在此模型中,一个只能属于一个实体;一个实体可以拥有(拥有)许多

model_mutually_exclusive_01

答案 2 :(得分:0)

你的链接表没问题。

您将遇到的麻烦是您需要在运行时生成动态sql。参数化的sql通常不允许FROM列表中的对象成为参数。

我想要避免这种情况,你可以稍微去规范化 - 比如通过创建一个表来保存id(假设id在其他表中是唯一的)和type_id表示哪个表是源,以及生成的描述 - 例如来自初始记录的名称值。

当修改基本信息时,您将触发创建此非规范化列表,并且可以将其用于通用查询 - 然后在运行时需要时使用动态查询。