首页 > 解决方案 > 我们如何根据 ERD 基数对外键列进行约束?

问题描述

假设我有 2 个如下表:

部门

DeptId   Name

员工

EmpId  Name    DeptId

Department在这里,我在和Employee表之间有一个 0 对多的关系。

Department现在,当我从to读取关系时Employee,它说 1 个部门可以有 0 个或更多员工。

这是否意味着在创建表时,由于零关系或多关系Employee,我将(外键)设置为空?DepartmentId

以及我们如何表示 1 个或多个关系,例如如果 ERD 中的关系说 1 个部门可以有 0 个或更多员工,那么DepartmentId(外键)在表中将不可为空Employee

基本上我只是想了解我们如何根据 ERD 基数(1 到多关系,1 到零或多个关系)对外键进行约束。

谁能帮我解决这个困惑?我真的很感激:)

ERD

标签: sql-serverdatabasedatabase-designerd

解决方案


ERD 工具很棒,但最强大的设计工具仍然是自然语言、谓词和约束。因此,如有疑问,请使用纯文本编辑器而不是 ERD 工具。也不允许在设计阶段使用 NULL。

All attributes (columns) NOT NULL

[p x]   = predicate  x
(c x.y) = constraint x.y

PK = Primary Key
AK = Alternate Key (Unique)
FK = Foreign Key

从部门开始,这部分没有改变。

[p 1]由编号标识的部门DEPT_ID,命名DEPT_NAME存在。

(c 1.1)部门由部门编号标识。

(c 1.2)对于每个部门名称,只有一个部门具有该名称;对于每个部门,该部门只有一个名称。

department {DEPT_ID, DEPT_NAME} -- p 1
        PK {DEPT_ID}            -- c 1.1
        AK {DEPT_NAME}          -- c 1.2

案例一:Emp * ---- 1Dept

[p 2]员工编号识别EMP_ID,命名EMP_NAME,为部门工作DEPT_ID

(c 2.1)员工由员工编号标识。

(c 2.2) 每位员工只有一个姓名;对于每个员工姓名,可以有多个员工拥有该姓名。

(c 2.3)每位员工只为一个部门工作;每个部门可以有多个员工为该部门工作。

(c 2.4)如果员工为某个部门工作,则该部门必须存在。

employee {EMP_ID, EMP_NAME, DEPT_ID}  -- p 2
      PK {EMP_ID}                     -- c 2.1, c 2.2, c 2.3

      FK {DEPT_ID} REFERENCES department {DEPT_ID} -- c 2.4

案例2:Emp * ---- 0..1Dept

[p 2]EMP_ID存在由 number 、named标识的员工EMP_NAME

(c 2.1)员工由员工编号标识。

(c 2.2) 每位员工只有一个姓名;对于每个员工姓名,可以有多个员工拥有该姓名。

[p 3]编号标识的员工为编号EMP_ID标识的部门工作DEPT_ID

(c 3.1)每名员工最多为一个部门工作;每个部门可以有多个员工在该部门工作。

(c 3.2)如果员工为某个部门工作,那么该员工必须存在。

(c 3.3)如果员工为一个部门工作,那么该部门必须存在。

employee {EMP_ID, EMP_NAME}  -- p 2
      PK {EMP_ID}            -- c 2.1, c 2.2


emp_dept {EMP_ID, DEPT_ID}  -- p 3
      PK {EMP_ID}           -- c 3.1

      FK1 {EMP_ID}  REFERENCES employee   {EMP_ID}  -- c 3.2
      FK2 {DEPT_ID} REFERENCES department {DEPT_ID} -- c 3.3

案例3:Emp * ---- *Dept

[p 2]EMP_ID存在由 number 、named标识的员工EMP_NAME

(c 2.1)员工由员工编号标识。

(c 2.2) 每位员工只有一个姓名;对于每个员工姓名,可以有多个员工拥有该姓名。

[p 3]编号标识的员工为编号EMP_ID标识的部门工作DEPT_ID

(c 3.1)每位员工可以多个部门工作;每个部门可以有多个员工在该部门工作。

(c 3.2)如果员工为某个部门工作,那么该员工必须存在。

(c 3.3)如果员工为一个部门工作,那么该部门必须存在。

employee {EMP_ID, EMP_NAME}  -- p 2
      PK {EMP_ID}            -- c 2.1, c 2.2


emp_dept {EMP_ID, DEPT_ID}  -- p 3
      PK {EMP_ID, DEPT_ID}  -- c 3.1

      FK1 {EMP_ID}  REFERENCES employee   {EMP_ID}  -- c 3.2
      FK2 {DEPT_ID} REFERENCES department {DEPT_ID} -- c 3.3

案例4:Emp * ---- 1..*Dept

这个很棘手,通过引入家庭(主要,默认)部门的概念来结合案例 1 和 3。

[p 2]员工编号识别EMP_ID,命名EMP_NAME,为家庭部门工作HOME_DEPT_ID

(c 2.1)员工由员工编号标识。

(c 2.2) 每位员工只有一个姓名;对于每个员工姓名,可以有多个员工拥有该姓名。

(c 2.3)每位员工只为一个家庭部门工作;对于每个家庭部门,可以有不止一名员工为该家庭部门工作。

(c 2.4)如果员工为所属部门工作,则该部门必须存在。

[p 3]除本部门外,编号标识的员工EMP_ID还为编号标识的另一个部门工作DEPT_ID

(c 3.1)除本部门外,每位员工可以多个其他部门工作;每个部门可以有多个员工为该部门工作。

(c 3.2)如果员工为某个部门工作,那么该员工必须存在。

(c 3.3)如果员工为一个部门工作,那么该部门必须存在。

employee {EMP_ID, EMP_NAME, HOME_DEPT_ID}  -- p 2
      PK {EMP_ID}                          -- c 2.1, c 2.2, c 2.3

      FK {HOME_DEPT_ID} REFERENCES department {DEPT_ID} -- c 2.4


emp_dept {EMP_ID, DEPT_ID}  -- p 3
      PK {EMP_ID, DEPT_ID}  -- c 3.1

      FK1 {EMP_ID}  REFERENCES employee   {EMP_ID}  -- c 3.2
      FK2 {DEPT_ID} REFERENCES department {DEPT_ID} -- c 3.3

在应用程序级别检查,对于给定的员工,HOME_DEPT_ID是否EMP_IDemp_dept.


推荐阅读