mysql - 围绕继承结构设计关系

标签 mysql laravel database-design relational-database

我有一个关于如何最好地组织我的数据库的概念性问题。

目前我有四个核心表usersteachersstudentsnotifications。但是 teachersstudents 表都继承自 users 表,因此包含外键 user_id

您可能已经猜到,notifications 表是指通知。这些需要为属于员工组的所有用户显示,即受雇于另一名员工。

学生和老师都可以雇佣其他用户。

所以关键是我需要一种 Eloquent 方式来对此进行建模。代码的基本工作流程如下:

getCurrentUser->getAllEmployer(s)->getNotifications

这是我习惯的 Laravel Eloquent $user->employers()->notifications;

不幸的是,事情并没有那么简单,在这种情况下,雇主可以引用两个表格。

所以我的选择如下。

  1. 学生老师 建立良好的关系 作为雇主的关系。不足之处是我需要写如果 测试以检查当前用户是否属于其中一个和此代码 会经常重复。
  2. 添加一个 teacher_idstudent_idusers 表。然而,每个人显然都是多余的 记录。很有可能需要添加其他列,因为 很好,因为新雇主实体的出现。
  3. 创建一个 employer_employee 表,其中包含两列均引用 user_id。 SQL 查询将同时加入 studentteacher 表与 employer_employee 表,然后是 JOIN 使用 notifications 将返回所有相关信息。然而会 与 其他选项。
  4. 我没有考虑过的事情。

我真的在寻找最高效、可扩展的解决方案。

感谢任何帮助。如果您能阐明为什么您的答案也是最有效的可扩展解决方案,那就太好了。

最佳答案

有个类似的问题here使用媒体父类(super class)型并添加 CD、VCR、DVD 等子类型。

这是可扩展的,因为在创建 BluRay 子类型时,您创建表以包含 BluRay 特定数据并向 MediaTypes 表添加一个条目。无需对现有数据或代码进行任何更改——当然,除了添加适用于蓝光数据的代码。

在您的情况下,用户将是父类(super class)型表,教师和学生是子类型表。

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 )
);

Students 表的构成与 Teachers 表类似。

由于教师和学生都可能雇用其他教师和学生,因此包含此关系的表将引用 Users 表。

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;

当然,这是一个初始草图。改进是可能的。但是对于你的编号点:

  1. 就业表将雇主与雇员联系起来。唯一检查是否使用户雇主不能雇用自己,否则任何用户都可以既是雇员又是雇主。
  2. Users 表强制每个用户是教师 ('T') 或学生 ('S')。只有定义为“T”的用户才能放在教师表中,只有定义为“S”的用户才能放在学生表中。
  3. Employment 表仅连接到 Users 表,而不连接到 Teachers 和 Students 表。但这是因为教师和学生既可以是雇主又可以是雇员,而不是出于任何绩效原因。通常,在初始设计期间不必担心性能。此时您主要关心的是数据完整性。关系数据库非常适合连接。 如果出现性能问题,请修复它。不要为了解决尚未存在或可能永远不会存在的问题而重组数据。
  4. 好吧,试一试,看看效果如何。

关于mysql - 围绕继承结构设计关系,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32574929/

相关文章:

javascript - 如何使用vue将对象传递给select中的方法?

sql - 如何在 MySQL 中强制执行复合唯一性?

php - 搜索不返回多个关键字的结果

java - 使用多线程更新数据库时如何避免 "lock timeout"?

php - 如何部署 CodeIgniter/Laravel 应用程序

php - 使用 Omnipay 和 Laravel 4 通过 Paypal Express 结账列出多个商品

database - 与传统的 RDBMS 实现相比,较新的数据库模型如何实现更好的可伸缩性和性能?

mysql - 关系数据库设计场景

mysql - 在 tomcat7 中部署 Web 应用程序

c# - 需要一点帮助来完成通用的 MySQL 选择方法