使用关联表和层次结构

时间:2018-02-02 05:46:00

标签: sql sql-server rdbms

在对实体进行建模时,将所有关系建模为关联实体而不是使用更多层次结构的原因是什么。例如,考虑两个表containeritem

选项A(亲子,1:多):

create table container (
    id    int   identity(1,1) primary key,
)

create table item (
    id          int  identity(1,1) primary key,
    containerId int  references container(id)
)

选项B(关联表,1:多)

create table container (
    id    int   identity(1,1) primary key,
)

create table item (
    id    int  identity(1,1) primary key,        
)

create table container_items (
    containerId int  references container(id),
    itemId      int  references item(id),
    PRIMARY KEY (itemId)        
)

这两种结构都取得了相同的结果,但为我们提供了不同的特征。

选项A是建模关系的更传统的方式,并在我们得到行结果时为我们提供项目数据。

选项B要求我们创建额外的索引以实现我们的约束,并且需要额外的连接来获取项目详细信息。另一方面,它将我们的item实体与容器分离,现在我们可以将它与其他实体相关联,而无需引用容器ID。我们还有适当的结构,可以在需要时轻松转换为许多表格。

围绕选项B进行设计允许我们在根级别对所有实体进行建模,并轻松形成交叉关联。这种设计似乎非常适合与诸如redux之类的web库一起使用,后者可以从规范化的JSON中受益。

B提供的其他优点/缺点是什么?

2 个答案:

答案 0 :(得分:1)

在选项A中,您有意限制关系(一对多)和选项B,如果您打算在"一对多"中使用它。格式化您开放数据完整性错误的可能性。这是因为在选项B中,有很多对很多人。关系是可实现的(以及在关系数据库中拥有关联表的主要原因)。此外,如果您不需要真正的"一对多"你之间的关系只是让你自己无缘无故地查询速度/资源。

然而,我可以想到你可能想要在一对多的情况下接受这种风险的潜在原因。 relationship ...如果在关联表中,您有其他列,这些列专门与两个表(容器和项)之间的特定关系相关。

例如....'容器1'可能与项目A'有关系。和'项目B'。但是,数量是您在关联表中提供的附加列。因此,您现在可以正确地保留该数据,以便关联表在这种情况下维护两行:

id - container_name

1 - 容器1

id - item_name

1 - 项目A

2 - 项目B

container_id - item_id - 数量

1 (容器1) - 1 (项目A) - 2

1 (容器1) - 3 (项目B) - 4

答案 1 :(得分:0)

长话短说:

选项A

这是您应该为“一对多”关系实施的设计

选项B

正如ThatTechGuy所提到的,这是你应该为“多对多”关系实现的设计。

如果您只有父子(一对多)关系,我不建议使用选项B.当你有一个关联表(也就是交集表)时,SQL查询会更麻烦一些(你需要2个连接来构建你的层次结构),它也会影响大量数据的性能。