在SQL Server中实现Polymorphic Association的最佳方法是什么?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在SQL Server中实现Polymorphic Association的最佳方法是什么?相关的知识,希望对你有一定的参考价值。

我有很多实例需要在我的数据库中实现某种多态关联。我总是浪费大量的时间来思考所有的选择。这是我能想到的3。我希望有一个SQL Server的最佳实践。

这是多列方法

这是没有外键的方法

这是基表方法

答案

两种最常用的方法是Table Per Class(即基类的表和每个子类的另一个表,其中包含描述子类所需的其他列)和Table Per Hierarchy(即一个表中的所有列,包含一个或多个列允许区分子类。哪种更好的方法实际上取决于您的应用程序和数据访问策略的细节。

在第一个示例中,您可以通过反转FK的方向并从父项中删除额外的ID来使用Table Per Class。另外两个基本上是每个类的表的变体。

另一答案

此模型的另一个常见名称是超类型模型,其中一个具有一组基本属性,可以通过连接到另一个实体进行扩展。在Oracle书籍中,它既是逻辑模型,也是物理实现。没有关系的模型将允许数据增长到无效状态和孤立记录,我会在选择该模型之前强烈验证需求。具有存储在基础对象中的关系的顶部模型将导致空值,并且在字段相互排斥的情况下,您将始终具有空值。在子对象中强制执行密钥的底部图将消除空值,但也会使依赖性成为软依赖性,并且如果未强制执行级联,则允许孤立。我认为评估这些特征将帮助您选择最适合的模型。我过去曾经使用过这三种颜色。

另一答案

我使用以下解决方案来解决类似的问题:

基于许多的设计:即使关系是ObjectN和Something之间的1-Many,它也相当于关系表的PK修改的Many-Many关系。

首先,我在Object和Something per Object之间创建一个关系表,然后我使用Something _ID列作为PK。

这是Something-Object1关系的DDL,对于Object2和Object3也是如此:

CREATE TABLE Something
(
    ID INT PRIMARY KEY,
    .....
)

CREATE TABLE Object1
(
   ID INT PRIMARY KEY,
   .....
)

CREATE TABLE Something_Object1
(
    Something_ID INT PRIMARY KEY,
    Object1_ID INT NOT NULL,
    ......

    FOREIGN KEY (Something_ID) REFERENCES Something(ID),
    FOREIGN KEY (Object1_ID) REFERENCES Object1(ID)
)

此票证multiple-foreign-keys-for-the-same-business-rule中的其他可能选项的更多详细信息和示例

另一答案

据我所知,你的第一种方法是你可以定义数据和类的最佳方法但是因为你的所有主要数据应该对孩子有用。

因此,您可以检查您的要求并定义数据库。

另一答案

我已经使用了我猜你会称之为基表的方法。例如,我有名称,地址和语音的表,每个表都有PK身份。然后我有一个主实体表实体(entityID)和一个链接表:attribute(entityKey,attributeType,attributeKey),其中attributeKey可以指向前三个表中的任何一个,具体取决于attributeType。

一些优点:允许每个实体使用尽可能多的名称,地址和语音,易于添加新属性类型,极端规范化,易于挖掘公共属性(即识别重复人员),以及其他一些特定于业务的安全优势

缺点:构建简单结果集的相当复杂的查询使得难以管理(即我很难雇用具有足够好的T-SQL排骨的人);对于非常具体的用例而言,性能是最佳的,而不是一般的;查询优化可能很棘手

除了我有相同的奇怪的业务逻辑约束和访问模式之外,在更长的职业生涯中使用这种结构已有好几年了,我会犹豫再次使用它。对于一般用法,我强烈建议您的类型表直接引用您的实体。即,实体(entityID),Name(NameID,EntityID,Name),Phone(PhoneID,EntityID,Phone),Email(EmailID,EntityID,Email)。您将有一些数据重复和一些常见的列,但编程和优化将更容易。

另一答案

方法1是最好的,但是某事物与object1,object2,object3之间的关联应该是一对一的。

我的意思是子(object1,object2,object3)表中的FK应该是非null唯一键或子表的主键。

object1,object2,object3可以具有Polymorphic对象值。

另一答案

没有单一或通用的最佳实践来实现这一目标。这一切都取决于应用程序所需的访问类型。

我的建议是概述这些表的预期访问类型:

  1. 你会使用OR层,存储过程还是动态SQL?
  2. 你期望有多少记录?
  3. 不同子类之间的差异程度是多少?多少列?
  4. 你会做聚合或其他复杂的报道吗?
  5. 您是否有报告数据仓库?
  6. 您是否经常需要在一个批处理中处理不同子类的记录? ...

根据这些问题的答案,我们可以找到一个合适的解决方案。

存储特定于子类的属性的另一种可能性是使用具有名称/值对的表。如果存在大量不同的子类或者不经常使用子类中的特定字段,则此方法特别有用。

另一答案

我使用了第一种方法。在极端负载下,“Something”表成为瓶颈。

我采用了为我的不同对象提供模板DDL的方法,并将属性特化附加到表定义的末尾。

在数据库级别,如果我真的需要将我的不同类表示为“Something”记录集,那么我将视图放在它们的顶部

SELECT "Something" fields FROM object1
UNION ALL
SELECT "Something" fields FROM object2
UNION ALL
SELECT "Something" fields FROM object3

鉴于你有三个独立的对象,你面临的挑战是如何分配一个非冲突的主键。通常人们使用UUID / GUID,但在我的情况下,密钥是基于时间和机器在应用程序中生成的64位整数,以避免冲突。

如果采用这种方法,则可以避免“Something”对象导致锁定/阻塞的问题。

如果你想改变“Something”对象,那么现在你有三个独立的对象可能会很尴尬,所有这些对象都需要改变它们的结构。

总结一下。选项一在大多数情况下都可以正常工作,但是在严重负载下,您可能会发现锁定阻塞,这需要拆分设计。

另一答案

具有多列外键的方法1是最好的。因为这样,您可以与其他表进行预定义的连接,这使脚本更容易选择,插入和更新数据。

以上是关于在SQL Server中实现Polymorphic Association的最佳方法是什么?的主要内容,如果未能解决你的问题,请参考以下文章

在 SQL Server 中实现一对零或一关系

有没有啥简单的方法可以在 Linq 中实现 SQL Server 的合并查询?

我应该如何在 SQL Server 2005 中实现“自动编号”字段?

在具有 Alwayson 设置的 SQL Server 中实现表分区

在SQL SERVER中实现RSA加解密函数(第二版)

是否可以使用实体框架在 SQL Server CE 中实现 CommitMode.Immediate