我正在建模一个实体关系图并卡住了。我不确定我的考虑是否错误,或者 ERD 无法模拟我想要的:
我有三个实体:员工、项目和角色。Employee 和 Project 之间有一个关系:一个员工正在做一个项目。但是这个员工不仅仅是在这个项目上工作,他/她有一个作为角色被赋予的操作领域。但是关系不只是由属性描述的吗?我怎样才能做出类似“一名员工在这个项目上工作......”之类的东西?当然,我可以使用 roleId 作为属性,因为我会将其设计为数据库,但是 ERD 中的关系是什么?
我正在建模一个实体关系图并卡住了。我不确定我的考虑是否错误,或者 ERD 无法模拟我想要的:
我有三个实体:员工、项目和角色。Employee 和 Project 之间有一个关系:一个员工正在做一个项目。但是这个员工不仅仅是在这个项目上工作,他/她有一个作为角色被赋予的操作领域。但是关系不只是由属性描述的吗?我怎样才能做出类似“一名员工在这个项目上工作......”之类的东西?当然,我可以使用 roleId 作为属性,因为我会将其设计为数据库,但是 ERD 中的关系是什么?
如果一个员工每个项目只能有一个角色:
如果一个员工每个项目只能有 1 个以上的角色:
两者的区别在于复合主键在后一个版本中包含角色。作为所有三列的复合主键,值的组合必须是唯一的,使得以下内容有效:
project_id employee_id role_id
---------------------------------
1 1 1
1 1 2
而如果 role_id不包含在复合主键中,则只能将用户和项目组合在一起 - 这意味着用户只能拥有一个角色。
CHECK 约束不起作用——它只检查行,而不是整个表。虽然触发器可以工作,但当您可以通过复合主键或唯一约束强制执行关系时,为什么还要麻烦呢?触发器在 ERD 中不可见,也不像CREATE TABLE
or之类的语句DESC table_name
。
在我设计数据库之前,我想将问题建模为实体关系图(使用 Chen 的符号)。在此图中,我想在员工和项目之间创建关系,而无需查看随后的键和约束。附录:我只知道通过属性扩展的两个实体之间的关系,但是我如何建模这种“三实体关系”?
这是完全可以理解的,也非常正确。纸很便宜,数据库中的对象更改起来有点贵。为需求建模并不断改进它,直到您有信心,然后实施。
许多网站的问题是,有许多木匠虽然好心,但将每个问题都视为钉子,并提供 DDL,而不是请求的建模帮助。缺少的是上下文和含义,因此最终结果是具有固定“键”但缺乏上下文和含义的硬性实现。建模允许我们对与我们相关的各个方面进行建模,而不用担心在 DDL 中会是什么样子。
另一种说法是,OMG 已经回答了一个问题,我该如何建模“一名员工在这个项目上工作...”?隔离中; 我在上下文中回答你的整个问题。
在逻辑层面,多对多关系是正确的。这种不考虑其他因素的关系在物理级别呈现为关联表。但同样,现在决定这一点还为时过早,因为您仍在对关系的上下文和含义进行建模。
...提供它也不属于 SO 降价符号的范围。IME、Oracle Designer 等工具在您创建实体后生成此类图表
废话。建模的整个想法是在纸上开发和改进某些东西,使用图表,早在编写一行代码、购买平台或必须实现 DDL 之前。评论只是事后对现有数据库进行逆向工程,这是许多产品提供的。
使用对您有意义的任何符号来建模您需要的东西。当然,标准符号更容易被普遍理解。这是
为您准备的 ERD
(我不知道“SO markdown notation”如何对提供事前建模建议造成限制)。我提供了一个可能发生的进展的例子。没有什么是“对”或“错”,都是纸上谈兵;直到您决定哪些元素值得确认,然后才有可能进行下一步。
起点当然是简单的多对多关系,根据你的标题,你知道一些事情。试图对概念上的三向关系进行建模是不正确的,这是一个建模错误:为了解决三角恋,您首先需要分别识别每一方之间的离散关系;这意味着所有关系都是双向的。
项目、员工和角色实体很清楚,我们对它们有所了解。在这里我把主要的实体不展开,因为它们是“强”的,它们不是你所关注的。
进程使用关系的示例属性,您可以使用自己的。(我们的比利时同事已经用文字指出了这个问题,我只是在图片中提供它。)人们通常不会做很多事情,他们应该做;我关心真正的建模,从上到下,以便取得进展并得出正确的数据模型。删除任何垃圾,然后继续前进。
我已经假设关系的属性证明了一个实体,所以我现在把它们画了进去。这里我使用了椭圆,你可以使用菱形或 V 形,只要使用一些符号,来建模你需要的东西.
我们可以清楚地看到这一点:我们不想要 Project::Employee::Role,因为这将允许 Employee 执行任何角色;我们希望员工只有在之前已被批准担任该角色时才被选中。因此,Employee::Role 正在变得“更强大”。
因此,Employee::Role 是一个实体。粉红色的 Thing 是该特定组合或 Employee+Role 的子代,而不是所有 Employee 或所有 Role 的子代。
同样,我们不希望任何员工在任何可能的项目中从事任何可能的工作,我们希望他们仅在已批准的项目中从事已批准的工作。所以 Project::Role 正在成为一个强大的身份,无论如何它都有属性。
因此,Project::Role 是一个实体。剩下的椭圆是 Project+Role 的特定组合的子项,而不是所有 Project 的子项。
我们的粉红色孩子获得实体状态,具有其特定属性。更重要的是,它的约束是从以前受约束的实体派生的,而不是简单的。
数据具有自然的顺序或层次结构,考虑到这一点绘制的图表很容易理解。我们现在有机会查看属性。它们可能看起来相同或相似或令人困惑;而现在,由于上下文和层次结构,它们具有明确的含义。
我已经介绍了Identifiers的概念,没有扩展它,如果有必要,我将留待讨论。我认为您可以看到标识符实际上非常非常重要,并且它们作为建模练习的普通部分公开。
一般而言(您的问题,与我的示例进程相反),当我们进行标准化时,三个初始椭圆可能最终成为一个或两个或保留为三个对象;没有属性的简单关联表;或作为具有属性的真正实体......但我们现在不关心也不应该关心这个。同样,对于 DDL 或现阶段的规范化来说,现在还为时过早。我们几乎不知道键是什么。什么属性与它们相关联;以及与他们有什么关系。更何况,我们不在乎。就示例而言,是的,实体是清晰明确的。
请反馈,以便您可以进步。
编辑:图表更新,多页。
“在我设计数据库之前,我想将问题建模为实体关系图(使用 Chen 的符号)。在这个图中,我想在员工和项目之间创建关系,而无需查看随后的键和约束。”
如果两者(员工和项目)之间的“有效”关系是多对多的,并且该关系具有描述(/提供有关该关系的更多详细信息)(发生)的更多属性,那么您通常没有其他属性选择但“实例化”关系,即将它定义为一个额外的实体。一些工具支持允许为任何关系指定附加属性的 ERD 方言(在指向关系箭头的圆角框中),但这不是 imo 常见的做法。