【问题标题】:ERD - How to model a relation between two entites with a third entity as "attribute"ERD - 如何将两个实体与第三个实体之间的关系建模为“属性”
【发布时间】:2011-05-04 04:41:06
【问题描述】:

我正在建模一个实体关系图并卡住了。我不确定我的考虑是否错误,或者 ERD 无法模拟我想要的:

我有三个实体:员工、项目和角色。 Employee 和 Project 之间有一个关系:一个员工正在做一个项目。但是这个员工不仅仅是在这个项目上工作,他/她有一个作为角色被赋予的操作领域。但是关系不只是由属性描述的吗?我怎样才能做出类似“一名员工在这个项目上工作......”之类的东西?当然,我可以将 roleId 用作属性,因为我会将其设计为数据库,但是 ERD 中的关系是什么?

【问题讨论】:

    标签: database-design data-modeling entity-relationship erd


    【解决方案1】:

    如何建模关系...实体...属性?

    在我设计数据库之前,我想将问题建模为实体关系图(使用 Chen 的符号)。在此图中,我想在员工和项目之间创建关系,而无需查看随后的键和约束。 附录:我只知道通过属性扩展的两个实体之间的关系,但是我如何建模这种“三实体关系”?

    这是完全可以理解的,也非常正确。纸很便宜,数据库中的对象更改起来有点贵。为需求建模并不断改进它,直到您有信心,然后实施。

    许多网站的问题是,有许多木匠虽然好心,但将每个问题都视为钉子,并提供 DDL,而不是请求的建模帮助。缺少的是上下文和含义,因此最终结果是具有固定“键”但缺乏上下文和含义的硬性实现。建模使我们能够对与我们相关的各个方面进行建模,而不必担心在 DDL 中会是什么样子。

    另一种说法是,OMG 已经回答了一个问题我如何将“一个员工在这个项目上工作为......”?我正在根据上下文回答您的整个问题。

    在逻辑层面,多对多关系是正确的。这种关系没有其他考虑在物理级别呈现为关联表。但同样,现在决定这一点还为时过早,因为您仍在对关系的上下文和含义进行建模。

    ... 也不在 SO 降价符号的范围内提供它。 IME、Oracle Designer 等工具会在您创建实体后生成此类图表

    废话。建模的整个想法是在纸上开发和改进某些东西,使用图表,早在编写一行代码、购买平台或必须实现 DDL 之前。评论只是事后对现有数据库进行逆向工程,许多产品都提供了。

    建模、进度示例

    使用对您有意义的任何符号来模拟您需要的东西。当然,标准符号更容易被普遍理解。这是一个
    ERD for you
    (我不知道“SO markdown notation”如何限制提供事前建模建议)。我提供了一个可能发生的进展的例子。没有什么是“对”或“错”,都是纸上谈兵;直到决定哪些元素值得确认,然后才有可能进行下一步。

    1. 起点当然是简单的多对多关系,根据您的标题,您知道一些事情。试图对概念上的三向关系进行建模是不正确的,这是一个建模错误:为了解决三角恋,您需要首先分别识别每一方之间的离散关系;这意味着所有关系都是双向的。

    2. 项目、员工和角色实体很清楚,我们对它们有所了解。在这里我把主要的实体留给了未开发的,因为它们很“强大”,而且它们不是你所关注的。

    3. 进度使用示例关系的属性,您可以使用自己的。 (我们的比利时同事已经用文字指出了这个问题,我只是在图片中提供它。)人们通常不会做很多事情,他们应该做;我关心真正的建模,从上到下,以便取得进展并得出正确的数据模型。删除任何垃圾,然后继续前进。

    4. 我已经假设关系的属性证明了一个实体,所以我现在把它们画了进去。这里我使用了椭圆形,你可以使用菱形或人字形,只要我关心,只需使用一些符号来建模您需要的东西。

    5. 我们可以清楚地看到这一点:我们不想要 Project::Employee::Role,因为这将允许 Employee 执行任何角色;我们希望员工只有在之前已被批准担任该角色时才被选中。因此,Employee::Role 正在变得“更强大”。

    6. 因此,Employee::Role 是一个实体。粉红色的 Thing 是该特定组合或 Employee+Role 的子代,而不是所有 Employee 或所有 Role 的子代。

    7. 同样,我们不希望任何员工在任何可能的项目中担任任何可能的工作,我们希望他们仅在已批准的项目中担任已批准的工作。所以 Project::Role 正在成为一个强身份,它无论如何都有属性。

    8. 因此,Project::Role 是一个实体。剩下的椭圆是 Project+Role 的特定组合的子项,而不是所有 Project 的子项。

    9. 我们的粉红色孩子获得实体状态,具有其特定属性。更重要的是,它的约束是从以前受约束的实体派生的,而不是简单的。

    10. 数据具有自然的顺序或层次结构,考虑到这一点绘制的图表很容易理解。我们现在有机会查看属性。它们可能看起来相同或相似或令人困惑;而现在,由于上下文和层次结构,它们具有明确的含义。

    我已经介绍了标识符的概念,没有展开它,如果有必要我将留待讨论。我认为您可以看到,标识符实际上非常非常重要,并且它们作为建模练习的普通部分公开。

    一般而言(您的问题,与我的示例进程相反),当我们进行规范化时,三个初始椭圆可能最终成为一两个或保留为三个对象;没有属性的简单关联表;或作为具有属性的真正实体......但我们现在不关心也不应该关心这个。同样,对于 DDL 或现阶段的规范化来说,现在还为时过早。我们几乎不知道键是什么。什么属性与它们相关联;以及与他们有什么关系。更何况,我们不在乎。就示例而言,是的,实体清晰明确。

    请反馈,以便您进步。

    编辑:图表已更新,多页。

    【讨论】:

    • 哇,感谢您非常详细的回答和示例。正如您所说,现在我必须决定是否使用一种易于建模但作为标准不正确的方法,或者我是否使用更困难的标准建模。我必须考虑一下,但我敢肯定,这样做的方法是您答案的一部分。
    • @Matthias:嗯。不,我所有的工作都严格遵守IDEF1X 标准。问题是,您无法从标准(声明)中学习方法,例如,您无法从食谱中学习成为厨师;您必须了解方法并有一些经验,解决问题,欣赏标准的价值,然后学习标准并改进/遵守。很多东西只能从导师那里学习,而不是书本。这就是为什么我说“做吧,模特”,不要担心是对是错,它会增进你的理解。
    • @Matthias:你能看到我使用了一个简单的绘图工具,而不是一个兼容 IDEF1X 的建模工具吗?这是一个简单的IDEF1X Model。即使在那里,我也使用了同样简单的绘图工具。标准不在工具中,也不在我的手中。
    【解决方案2】:

    员工

    • employee_id (pk)

    项目

    • project_id (pk)
    • project_description

    角色

    • role_id (pk)
    • 角色描述

    如果一个员工每个项目只能有一个角色:

    EMPLOYEE_PROJECT_MAP

    • project_id(pk,fk 到 PROJECT)
    • employee_id(pk,fk 到 EMPLOYEE)
    • role_id(fk 到 ROLE)

    如果一个员工每个项目只能有 1 个以上的角色:

    EMPLOYEE_PROJECT_MAP

    • project_id(pk,fk 到 PROJECT)
    • employee_id(pk,fk 到 EMPLOYEE)
    • role_id (pk, fk to ROLE)

    两者的区别在于复合主键在后一个版本中包含角色。作为所有三列的复合主键,值的组合必须是唯一的,使得以下内容有效:

    project_id  employee_id  role_id
    ---------------------------------
    1           1            1
    1           1            2
    

    而如果 role_id 包含在复合主键中,则只能一个用户和项目的组合 - 这意味着用户只能拥有一个角色。

    CHECK 约束不起作用 - 它只检查行,而不是整个表。虽然触发器可以工作,但当您可以通过复合主键或唯一约束强制执行关系时,为什么还要麻烦呢?触发器在 ERD 中不可见,CREATE TABLEDESC table_name 之类的语句也不可见。

    【讨论】:

    • 如果员工和项目包含在唯一索引中,那么您将无法输入多个。
    • @Randy:是的,唯一约束是主键的替代方案 - 两者都强制复合值作为一个集合是唯一的。
    • @OMG: 3. 您仍然缺少 role_id 的 FK(当然不包括在 PK 中)。 4. 就我个人而言,我只会选择第二个,加上一个 CHECK 约束以防止多个角色,如果将来需要,可以在不影响表数据的情况下删除它。
    • @Randy:但是桌子需要PK,提供的PK很完美;为什么要添加另一列(对于您想到的任何 PK)并添加另一个索引?令人难以置信。
    • @OMG:对于一个拿着锤子的木匠来说,每个问题都像钉子。 Matthias 处于建模阶段,而不是实施阶段。这个阶段的 DDL 还为时过早。它要么被扔掉,要么更糟糕的是,如果实施了,就必须改变它。
    【解决方案3】:

    “在我设计数据库之前,我想将问题建模为实体关系图(使用 Chen 的表示法)。在这个图中,我想在员工和项目之间创建关系,而不需要查看键和约束跟着。”

    如果两者(员工和项目)之间的“有效”关系是多对多的,并且该关系具有描述(/提供有关该关系的更多详细信息)(发生)的更多属性,那么您通常除了“实例化”关系之外别无选择,即将它定义为一个额外的实体。一些工具支持 ERD 方言,允许为任何关系指定附加属性(在箭头指向关系箭头的圆角框中),但这在 imo 中并不常见。

    【讨论】:

    • +1:Oracle Designer IME 为 1:many/many:many 的多边提供鱼尾纹,并为可选性(可空性)提供虚线
    • 早在 Oracle 孵化之前,就有一个Relational Modelling Standard,消除了这一切的困惑;它被尊重和实施独立、易于使用且性能良好的关系模型的专业人士和组织广泛接受。更严格的关系模型实现,促进了对键的正确处理。它具有出色的明确表示法。但是,对于关系表示法,IEEE 的“乌鸦脚”得到了更广泛的理解,因此大多数建模工具都允许您使用其中任何一种(仅用于关系)。
    猜你喜欢
    • 2018-07-29
    • 2022-01-23
    • 2021-04-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多