sql-server - 我们如何根据 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 工具很棒,但最强大的设计工具仍然是自然语言、谓词和约束。因此,如有疑问,请使用纯文本编辑器而不是 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 * ---- 1
Dept
[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..1
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} -- 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_ID
像emp_dept
.
推荐阅读
- pip - 如何使用 pip (certbot-dns-hetzner) 安装 SnapStore 中不可用的 certbot dns 插件
- scala - 递归价值链0需求类型
- javascript - 从函数外部访问从函数获取的值
- r - R中是否有一个函数可以将几个单独的图形打包成一个“Network.List”?
- python - 改变
至 - c - C 比较字符串时的警告
- c++ - 如何放置到 std::array 的 std::vector?
- python - Python-如何并行运行不同的 sql 查询
- google-apps-script - 尝试将电子表格脚本中的客人添加到日历应用程序
- assembly - r/m8 操作数被反汇编器解释为 r/m32 操作数