TL; DR
您的问题或多或少是必须在 DDL(数据定义语言)与EAV(实体-属性-值)之间做出决定的典型情况。
如果可以,请使用一张桌子
通常,您将拥有一张表,它是您正在谈论的所有表的并集。至于招生。
// student [student] is enrolled in [course]
Enrolment(student,course)
PK (student, course)
FK (student) to Student (student)
FK (course) to Course (course)
// user [user] likes page [page]
Likes(user,page)
PK (user, page)
FK (user) to User (user)
没有标准的 ER 方法来指示每个实体实例的表,即每个实体实例的关联集。那是因为您通常会有一个喜欢的页表,就注册而言。
约束用户表和关于表的表
有描述数据库本身的“元数据”表。(详细信息取决于 DBMS。)将有一个表,我将其称为 Table,其中有一列我将称为 tablename,每个数据库表都有一行,在 tablename 中保存其名称。您想要的“关系”,即约束,可以在 Table 和 User 表之间表达。(但不一定在特定的 SQL DBMS 中以声明方式。)
目前尚不清楚您要记录什么关系/约束。可能您至少想说,如果存在名称为 Likes_ user的表,那么它的用户就会存在。这不是 ER 图显示的那种“关系”/约束,它们是 FK(外键)。大多数(但不是全部)SQL DBMS 无法以声明方式表达这一点。它是NOT EXISTS(select tablename from Table where tablename like 'Likes_%' except select CONCAT('Likes_', user) as tablename from User)
。
您可以计算用户的表名并将其存储在用户列 likestablename 中,并声明一个FK Table (tablename) references User (likestablename)
. (如果您的 DBMS 允许,将 likestablename 声明为计算列。)如果您可以将可为空的用户列添加到表,那么您可以声明“FK 表(用户)引用用户(用户)。但是你不能,因为它是一个系统表。您可以声明一个视图,但 SQL 不允许您在视图中声明 FK。
您可能还希望每个 User 用户在 Table 表名中都有一个表名。那就是
NOT EXISTS(select CONCAT('Likes_', user) as tablename from User except select tablename from Table where tablename like 'Likes_%')
。
如果 Table 表名值与 User 用户值一样,那么您可以改为声明 FK 用户(用户)引用表(表名)。由于它们不同,您可以使用 User 表名技术来声明一个FK User (tablename) references Table (tablename)
.
如果您想要这两个约束,那么您希望每个用户在两个表的某些行之间有一个精确 1 到精确 1(即“1 到 1 对应”)。即使对于所有行,在大多数 SQL DBMS 中都不容易以声明方式做到这一点,因为它们不允许表之间的双向 FK。通常,您可以通过将它们配对在同一个表中来处理所有行的情况。(可能涉及视图。)但在这里你不能因为 Table 是系统表。
如果您的Likes_
user
表有不同的列,那么它是 DDL 与 EAV
您可能希望每个表中有不同的列。那么确实可以有多个由 DML 和 DDL 管理的Likes_用户表,这很清楚并且完全使用 DBMS。但是,如果在测试和计算DDL成本后的这种不同列的情况下,您可以使用单个表以及多个表和/或空列。这些实现了一种技术“EAV”,否则它是一种反模式,因为您失去了很多 DBMS 功能。