问答中心分类: SQL如何在数据库中表示继承?
0
匿名用户 提问 9小时 前

我正在考虑如何在SQL Server数据库中表示复杂的结构。
考虑一个应用程序,它需要存储一系列对象的详细信息,这些对象共享一些属性,但还有许多其他属性不常见。例如,商业保险包可能包括同一保单记录中的责任险、汽车险、财产险和赔偿险。
在C#等语言中实现这一点很简单,因为您可以创建一个包含部分集合的策略,其中根据各种类型的保险的需要继承部分。然而,关系数据库似乎不容易做到这一点。
我可以看到有两个主要选择:

  1. 创建一个策略表,然后创建一个节表,其中包含所有可能的变体所需的字段,其中大多数为空。
  2. 创建一个保险单表和多个部分表,每种保险单一个。

这两种选择似乎都不令人满意,尤其是当需要跨所有部分编写查询时,这将涉及大量连接或大量空检查。
这种情况下的最佳做法是什么?

6 Answers
0
David 回答 9小时 前

第三个选项是创建一个“策略”表,然后是一个“SectionsMain”表,该表存储跨节类型的所有公共字段。然后为每种类型的节创建其他表,这些表只包含不常见的字段。
决定哪一个是最好的主要取决于您有多少字段以及您希望如何编写SQL。他们都会工作。如果你只有几个字段,那么我可能会选择#1。如果有“很多”字段,我会倾向于选择Ş2或35e3。

D'Arcy Rittich 回复 9小时 前

+1: 第三个选项最接近继承模型,也是最规范化的IMO

Steve Jones 回复 9小时 前

您的选项#3实际上正是我所说的选项;2。有许多字段,有些部分也会有子实体。

0
overcomer 回答 9小时 前

此外,在Daniel Vassallo解决方案中,如果您使用SQL Server 2016+,还有另一个解决方案,我在某些情况下使用了该解决方案,但没有显著的性能损失。
您可以只创建一个只有公共字段的表,然后添加一个具有公共字段的列JSON包含所有子类型特定字段的字符串。
我已经测试了这个管理继承的设计,我很高兴能在相关应用程序中使用这种灵活性。

Steve Jones 回复 9小时 前

这是一个有趣的想法。我还没有在SQL Server中使用JSON,但在其他地方经常使用它。谢谢你的提醒。

MatBailie 回复 9小时 前

这对于您不打算索引的数据来说非常好……如果您打算在WHERE子句等中使用列,那么您将希望对它们进行索引,而JSON模式禁止您在那里进行索引。

0
OMG Ponies 回答 9小时 前

根据提供的信息,我将对数据库进行建模,使其具有以下内容:
政策

  • 策略ID(主键)

债务

  • 责任ID(主键)
  • 策略ID(外键)

属性

  • PROPERTY_ID(主键)
  • 策略ID(外键)

…等等,因为我希望政策的每个部分都有不同的属性。否则,可能会有一个SECTIONS表和policy_id,会有一个section_type_code
无论如何,这将允许您支持每个策略的可选部分。。。
我不理解您对这种方法有什么不满意的地方——这是您在保持引用完整性和不复制数据的同时存储数据的方式。术语是“归一化的”。。。
因为SQL是基于集合的,所以它与过程/面向对象编程概念相当陌生&需要代码从一个领域过渡到另一个领域。经常考虑使用orm,但它们在高容量、复杂的系统中工作不好。

Steve Jones 回复 9小时 前

是的,我得到了归一化的东西;-)对于这样一个复杂的结构,有些部分很简单,有些部分有自己复杂的子结构,ORM似乎不太可能工作,尽管它很好。

0
Marco Paulo Ollivier 回答 9小时 前

另一种方法是使用INHERITS组成部分例如:

CREATE TABLE person (
    id int ,
    name varchar(20),
    CONSTRAINT pessoa_pkey PRIMARY KEY (id)
);

CREATE TABLE natural_person (
    social_security_number varchar(11),
    CONSTRAINT pessoaf_pkey PRIMARY KEY (id)
) INHERITS (person);


CREATE TABLE juridical_person (
    tin_number varchar(14),
    CONSTRAINT pessoaj_pkey PRIMARY KEY (id)
) INHERITS (person);

因此,可以在表之间定义继承。

giannis christofakis 回复 9小时 前

其他DBs支持吗INHERITS此外PostgreSQL?MySQL例如

a_horse_with_no_name 回复 9小时 前

@giannischristofakis:MySQL只是一个关系数据库,而Postgres是一个对象关系数据库。所以,没有MySQL不支持这一点。事实上,我认为Postgres是当前唯一支持这种类型继承的DBMS。

mapto 回复 9小时 前

@马可·保罗·奥利维尔(marco paulo ollivier),OP的问题是关于SQL Server的,所以我不明白为什么你提供的解决方案只适用于Postgres。显然,没有解决这个问题。

Caius Jard 回复 9小时 前

@映射到这个问题已经成为“如何在数据库中进行OO风格的继承”的重复目标;它最初是关于sql server的,现在可能无关紧要了

defraggled 回复 9小时 前

看来INHERITSpg功能允许更优雅的查询,但是表/列本身仍然以具体的继承方式设置:重复所有公共属性。我认为这并不能消除具体继承中已经出现的任何缺陷

0
Grigori Melnik 回答 9小时 前

或者,考虑使用本机支持丰富数据结构和嵌套的文档数据库(如MongoDB)。