我有一个关于如何最好地组织我的数据库的概念性问题。
目前,我有四个核心表users
,teachers
,students
和notifications
。但是teachers
和students
表都从users
表继承,因此包含外键user_id
。
您可能已经猜到的notifications
表引用了通知。这些需要出现在属于雇员组的所有用户中,即在另一个用户的雇佣下。
学生和教师都可以聘用其他用户。
所以关键是我需要一种雄辩的建模方法。代码的基本工作流程如下:
getCurrentUser->getAllEmployer(s)->getNotifications
这是Laravel Eloquent我曾经$user->employers()->notifications;
不幸的是,它并不像在这种情况下那样简单,雇主可以参考两个表格。
所以我的选择如下。
student
和teacher
创建雄辩的关系
作为雇主的关系。缺点是我需要写,如果
测试以检查当前用户是否属于该代码
会经常重复。teacher_id
和student_id
users
表。然而,每个人显然都是多余的
记录。需要添加其他列的可能性很大
很好,因为新雇主实体的出现。employer_employee
表,其中包含两个引用user_id
的列。 SQL查询将LEFT JOIN student
和。{
带有teacher
表的employer_employee
表,然后是JOIN
notifications
将返回所有相关内容。不过会
与此相比,如此多的连接会降低查询的速度
其他选择。我真的在寻找最有效,可扩展的解决方案。
感谢任何帮助。如果你能澄清为什么你的答案是最有效的可扩展解决方案,那将是一流的。
答案 0 :(得分:1)
有一个类似的问题here使用Media超类型并添加CD,VCR,DVD等子类型。
这是可扩展的,因为在创建BluRay子类型时,您创建表以包含特定于BluRay的数据并向MediaTypes表添加条目。现有数据或代码无需更改 - 当然,除了添加可与BluRay数据一起使用的代码。
在您的情况下,用户将是教师和学生的子类型表的超类型表。
create table Users(
ID int not null auto_generating,
Type char( 1 ) check( Type in( 'T', 'S' )),
-- other data common to all users,
constraint PK_Users primary key( ID ),
constraint UQ_UserType unique( ID, Type ),
constraint FK_UserTypes foreign key( Type )
references UserTypes( ID )
);
create table Teachers(
TeacherID int not null,
TeacherType char( 1 ) check( TeacherType = 'T' )),
-- other data common to all teachers...,
constraint PK_Teachers primary key( TeacherID ),
constraint FK_TeacherUser foreign key( TeacherID, TeacherType )
references Users( ID, Types )
);
学生表的构成与教师表类似。
由于教师和学生都可以雇用其他教师和学生,因此包含此关系的表格将引用“用户”表。
create table Employment(
EmployerID int not null,
EmployeeID int not null,
-- other data concerning the employment...,
constraint CK_EmploymentDupes check( EmployerID <> EmployeeID ),
constraint PK_Employment primary key( EmployerID, EmployeeID ),
constraint FK_EmploymentEmployer foreign key( EmployerID )
references Users( ID ),
constraint FK_EmploymentEmployee foreign key( EmployeeID )
references Users( ID )
);
据我了解,通知按雇主分组:
create table Notifications(
EmployerID int not null
NotificationDate date,
NotificationData varchar( 500 ),
-- other notification data...,
constraint FK_NotificationsEmployer foreign key( EmployerID )
references Users( ID )
);
查询应该足够简单。例如,如果用户想要查看来自其雇主的所有通知:
select e.EmployerID, n.NotificationDate, n.NotificationData
from Employment e
join Notifications n
on n.EmployerID = e.EmployerID
where e.EmployeeID = :UserID;
这是一个初步草图,当然。可以进行改进。但是到了你的编号点: