38

我们通过将一个表的 PK 作为 FK 添加到另一个表来实现一对多关系。我们通过将 2 个表的 PK 添加到第三个表来实现多对多关系。

我们如何实现 IS-A 关系?

实体是技术人员和行政人员,两者都是员工。我可以在表 EMPLOYEE(id, name, surname, role , ...AdminFields..., ...TechFields...)中使用一个额外的字段

但我想探索 IS-A 选项。

编辑:我按照唐尼的建议做了,但没有角色字段。

4

8 回答 8

29

我按照 Donnie 的建议做了,但没有角色字段,因为它使事情复杂化。这是最终的实现:

DDL:

CREATE TABLE Employee (
ast VARCHAR(20) not null,
firstname VARCHAR(200) not null,
surname VARCHAR(200) not null,
...
PRIMARY KEY(ast)
);

CREATE TABLE Administrative (
employee_ast VARCHAR(20) not null REFERENCES Employee(ast),
PRIMARY KEY(employee_ast)
);

CREATE TABLE Technical (
employee_ast VARCHAR(20) not null REFERENCES Employee(ast),
...
PRIMARY KEY(employee_ast)
);

ER图:

ERD

在此模型中,没有通用类型的员工。在这里,员工只能是管理人员或技术人员。

于 2011-01-12T09:09:50.680 回答
8

IS-A 关系也称为 gen-spec 设计模式。Gen-spec 是“泛化专业化”的缩写。

gen-spec 的关系建模与 gen-spec 的对象建模不同,因为关系模型没有内置继承。

这是一篇很好的文章,展示了如何将 gen-spec 实现为表的集合。

http://www.javaguicodexample.com/erdrelationalmodelnotes1.html

请特别注意在专用表中设置主键的方式。这就是使使用这些表格变得如此简单的原因。

您可以通过谷歌“泛化专业化关系建模”找到许多其他文章。

于 2010-12-06T08:58:12.213 回答
7

我总是用一个role字段来做这个,然后是可选的关系。

即表EMPLOYEE (id, ...generic fields... , role)

然后,对于每个角色:

桌子ROLE1 (employeeid, ...specific fields...)

这允许您通过单个查询获取一般员工信息,并且需要连接才能获取特定于角色的信息。这样做的一个(大)缺点是,如果您需要一个包含所有角色信息的超级报告,那么您会遇到一堆外部连接。

于 2010-12-05T21:45:18.927 回答
5

如果您有一个需要连接到关系后端数据库的 OO 应用程序,我建议您获取 Martin Fowler 的企业应用程序架构模式

他的网站上也有一些相关的注释和图表。具体来说,模式单表继承类表继承具体表继承描述了在数据表中映射 IS-A 的三种策略。

如果您使用的是 Hibernate 或 JPA,它们支持所有这些的映射,尽管它们有不同的名称。

在这种特定情况下,我根本不会使用 IS-A。

像员工角色这样的东西更好地建模为 HAS-A,因为

  1. 您可能希望一个人担任多个角色。
  2. 改变一个人的角色会更容易。
于 2010-12-05T22:37:57.950 回答
3

本文描述了将泛化映射到模式设计的一些策略。

http://www.sztaki.hu/conferences/ADBIS/3-Eder.pdf

摘要副本:

对象关系数据库更丰富的数据模型为数据库模式的逻辑设计提供了更多选择,极大地增加了逻辑数据库设计的复杂性。专注于概念模型的泛化构造,我们探讨了将泛化映射到对象关系数据库系统模式的各种设计方案的性能影响。

于 2010-12-05T22:42:25.043 回答
2

为什么不将其实现为一对零/一个表关系?假设您有一个表,表示名为 Vehicle 的基类,主键为 VehicleID。然后,您可以有任意数量的卫星表来表示 Vehicle 的所有子类,并且这些表也有 VehicleID 作为它们的主键,从 Vehicle->Subclass 具有 1->0/1 的关系。

或者,如果你想让它更简单,并且你确定你只会有几个子类并且改变的可能性不大,你可以只在一个带有鉴别器类型字段的表中表示整个结构.

于 2010-12-05T21:54:39.253 回答
1

大多数 ORM 使用单列鉴别器实现 IS-A 关系,根据特定列中的值选择要实例化的子类。关于您的示例,您可能并不是真的指角色,因为通常一个人可以担任许多不同类型的角色。角色通常会被建模为具有关系。如果您确实尝试使用is-a关系(或子类化)来实现它,那么您不可避免地最终不得不做一些更复杂的事情来处理您有一个人担任混合职位的情况 - 即同时担任本地职位的秘书IT 人员,需要两者的权限或属性。

于 2010-12-05T21:51:56.007 回答
1

这取决于您是在构建单层次结构还是多层次结构。这是一个硬编码的设计,我相信这就是你想要的。

对于mono(子表有一个父表),其中child IS-A parent,子表中的FK和PK是相同的,那个key也是父表中的PK。

对于 poly(子表有多个父表),其中 child IS-A parent-1 和 child IS-A parent-2,您将有一个复合键(意味着多个主键使表记录唯一),其中规则与每个键的单一层次结构相同。

于 2013-12-05T19:56:52.093 回答