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

Sql 我们如何实现IS-A关系?,sql,database,database-design,class-table-inheritance,Sql,Database,Database Design,Class Table Inheritance,我们通过将一个表的PK作为FK添加到另一个表来实现一对多关系。 我们通过向第三个表添加2个表的PK来实现多对多关系 我们如何实现IS-A关系 实体为技术人员和管理人员,两者均为员工。 我可以在表中使用一个额外的字段 员工(id、姓名、姓氏、角色、、…AdminFields…、…TechFields…) 但我想探讨IS-A选项 编辑:我按照Donnie的建议做了,但是没有角色字段。我总是使用角色字段,然后是可选的关系 例如,表EMPLOYEE(id,…通用字段…,角色) 然后,对于每个角色: 表R

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

我们如何实现IS-A关系

实体为技术人员和管理人员,两者均为员工。 我可以在表中使用一个额外的字段 员工(id、姓名、姓氏、角色、、…AdminFields…、…TechFields…)

但我想探讨IS-A选项


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

我总是使用
角色
字段,然后是可选的关系

例如,表
EMPLOYEE(id,…通用字段…,角色)

然后,对于每个角色:

ROLE1(员工ID,…特定字段…)


这允许您通过单个查询获取一般员工信息,并要求联接获取特定于角色的信息。这样做的一个(大的)缺点是,如果您需要一个包含所有角色信息的超级报表,那么您就会被一堆外部联接所困扰。

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

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


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

如果你有一个OO应用程序,你需要连接到一个关系型后端数据库,我建议买马丁·福勒的

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

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

在这个特定的例子中,我根本不会使用IS-A

像员工角色这样的东西最好建模为HAS-A,如

  • 你可能想要一个人 有多个角色
  • 改变一个人的角色将是 更容易

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

    摘要副本:

    更丰富的数据模型 对象关系数据库打开了许多 有关逻辑设计的更多选项 一个数据库模式增加了 逻辑数据库设计的复杂性 极大地注重泛化 概念模型的构造 探索性能影响 不同的设计方案 将泛化映射到 关系对象的模式 数据库系统


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

    genspec的关系建模不同于genspec的对象建模,因为关系模型没有内置继承

    这是一篇很好的文章,展示了如何将genspec实现为一个表集合

    请特别注意在专用表中设置主键的方式。这就是为什么使用这些表格如此容易的原因


    你可以在googlin的“泛化-专业化-关系建模”中找到许多其他文章。

    我按照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图:

    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)
    );
    


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

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

    对于mono(子表有一个父表),其中child是一个父表,子表中的FK和PK是相同的,并且该键也是父表中的PK


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

    IS-A本身不是一个关系。行的标识通常由包含它的表的名称定义。例如,表中名为
    employees
    的一行是雇员。如果要添加包含
    技术人员
    管理人员
    等的
    员工_类型
    枚举,则可以。但该表中的每一行仍然是employee@asah-我认为这意味着映射到子类,例如通过ORM。在这种情况下,技师将是域模型中雇员的一个子类,并且技师和雇员实体之间存在IS-a关系。也就是说,我不认为组织中的角色最好使用继承来建模。@asah-如果TECHNICIA