我正在考虑如何在SQL Server数据库中表示一个复杂的结构。

考虑这样一个应用程序,它需要存储一系列对象的详细信息,这些对象共享一些属性,但有许多其他不常见的属性。例如,一个商业保险包可能在同一份保单记录中包括责任、汽车、财产和赔偿。

在c#等语言中实现这一点很简单,因为您可以创建一个带有Sections集合的Policy,其中Section根据需要继承各种类型的封面。然而,关系数据库似乎不容易做到这一点。

我可以看到有两个主要的选择:

创建一个Policy表,然后创建一个Sections表,其中包含所有可能的变量所需的所有字段,其中大多数字段将为空。 创建一个Policy表和许多Section表,每个表对应一种封面。

这两种选择似乎都不能令人满意,特别是需要跨所有section编写查询,这将涉及大量连接或大量空检查。

这个场景的最佳实践是什么?


当前回答

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

其他回答

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

另一种方法是使用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);

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

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

政策

POLICY_ID(主键)

负债

ability_id(主键) POLICY_ID(外键)

属性

PROPERTY_ID(主键) POLICY_ID(外键)

...等等,因为我希望策略的每个部分都有不同的属性。否则,可能只有一个SECTIONS表,除了policy_id之外,还有一个section_type_code…

无论哪种方式,这将允许您支持每个策略的可选部分……

我不明白您对这种方法有什么不满意的地方——这就是存储数据的同时保持引用完整性和不复制数据的方式。术语是“正常化”…

因为SQL是基于SET的,它与过程式/OO编程概念相当陌生,并且需要代码从一个领域转换到另一个领域。通常会考虑orm,但它们在大容量、复杂系统中不能很好地工作。

除了Daniel Vassallo解决方案,如果您使用SQL Server 2016+,还有另一种解决方案,我在某些情况下使用,性能不会有相当大的损失。

您可以只使用公共字段创建一个表,并使用包含所有子类型特定字段的JSON字符串添加一个列。

我已经测试了这个设计的管理继承,我很高兴,我可以在相关应用程序中使用的灵活性。

第三个选项是创建一个“Policy”表,然后创建一个“SectionsMain”表,用于存储所有在不同类型的节中通用的字段。然后为每种类型的节创建其他只包含不相同字段的表。

决定哪种是最好的主要取决于您有多少字段以及您想如何编写SQL。它们都会起作用。如果你只有几个字段,那么我可能会选择#1。对于“很多”领域,我会倾向于#2或#3。