假设我有一个名为
User (Entity)
的表,其属性为_id, name, email, user_type [enum: "normal user", "admin", "volunteer"], address, and age
。另外,我还有另一个名为 Project (Entity)
的实体,其属性为 _id, title, start date, end date, and created_by
。管理员类型用户只能创建项目,因此其他 user_type
用户只能查看它。那么如何根据这个条件表示用户和项目实体之间的关系呢?我不想创建 3 个独立的实体 NormalUser、Admin 和 Volunteer,还是应该将它们分开?所有属性都相同,但权限不同。我能做什么?
admin 类型用户只能创建项目,因此其他 user_type 用户只能查看该项目。那么如何根据这个条件表示用户和项目实体之间的关系呢?
通过使用复合FK加上子表一侧的约束:
Users {
_id PK UK1
user_type UK1
...
}
Projects {
_id PK
created_by FK1 -> Users._id
created_by_type FK1 -> Users.user_type
...
CONTRAINT created_by_type = 'admin'
}
(我指定了复合 UK1,意味着唯一性约束,因为大多数 DBMS 只允许 FK 到唯一键,无论是简单键还是复合键。)
请注意,这保证了数据的完整性,即只有管理员才会出现在项目的created_by字段中:一个完全不同的问题是应用程序授权以及谁可以或尝试在应用级别执行什么操作以及何时执行。
一些附加说明:
事实上,最终甚至可以强制执行授权,即通过一些 UserActions(预)日志表,以便可以跨用户(其类型或角色)和可能的操作应用约束,尽管这种控制级别是一个极端,要求所有应用逻辑都编码在关系模型中:这远非不可能,并且提供了大量可能的代码生成,但需要在顶部有一个完整的功能规范,而不仅仅是关系数据模型。
顺便说一句,就 ERD 和关系数据库而言,实体名称确实应该是复数(好吧,所以我建议/声明:我不会强调这一点),这就是为什么我更改了上面的表名称。