mysql - 2个多对多关系的数据库建模

标签 mysql database database-design

我有 3 个实体

teacher :存储学校教师的姓名。 (例如“老师 1”、“老师 2”)
access :存储所有可能的访问类型的名称。 (例如“class_teacher”、“sports_teacher”、“head_master”)
classroom:存储学校不同类(class)的名称。 (例如“教室 I”、“教室 II”)

关系如下:

  • 教师<->访问是多对多的
  • 老师<->类是多对多的

我现在建模的方式如下表所示

  1. 教师(ID、用户名)(1 t1、2 t2)
  2. 访问(id,访问)(1 a1,2 a2)
  3. 教室(id、类(class))(1 c1、2 c2)
  4. teacher_access(id、teacherId、accessId)(1 1 1, 1 1 2)
  5. teacher_classroom(id、teacherId、classroomId)(1 1 1, 1 1 2)

teacher_access 中的一行存储特定“教师”拥有的特定“访问权限”。
例如(1 1 1)表明t1可以访问a1

teacher_classroom 中的一行允许特定的“教师”使用他/她拥有的访问权限来访问特定的“教室”。
例如(1 1 1)表明教师t1可以访问教室c1

这里的问题是我不想让教师 t1 访问教室 c2 的 a2 权限。

在我当前的设计中,如果teacher_access中有一行,则该行中的tId将具有由该行的aId指定的“访问权限”,对于我们在“teacher_classroom”中具有相同teacherId的行的所有教室。因此,如果我在“teacher_access”中有 2 行(tId =1,aId = 1),(tId = 1,aId = 2),在“teacher_classroom”中有 2 行(tId =1,cId =1),( tId = 1,cId = 2),“教师”(1) 具有两个“教室”(1,2) 的“访问权”(1,2)。但我想做的是仅为 cId(1) 提供 aId(1) 到 tId(1),并为 cId (2) tId : TeacherId aId : accessId cId:classroomId 提供 aId (1,2)。

我想说的是,我希望“老师”对不同的“教室”有不同的“访问权”。例如。教师可以同时拥有“class_teacher”和“sports_teacher”访问教室“classroom I”的权限,并且只有“sports_teacher”访问“classroom II”的权限。我无法使用我当前的设计来做到这一点,因为如果老师对每个teacher_access具有“访问权限”(sports_teacher,class_teacher)并且同一位老师可以访问“教室”(教室I,教室II),我不能让老师作为唯一的“sports_teacher”代表“教室 II”。

什么是更好的建模方法?

最佳答案

您可以通过教师、访问、教室和 table 描述正在发生的情况

"teacher TID has access AID to classroom CID"

根据您的编辑和评论:给定一位老师或一个访问权限或一间教室,一行的其余部分不仅仅只有一个值。给定老师和教室,可能会有多种访问。如果有老师和访问权限,可能会有多个房间。只要有 channel 和房间,就可以有多名教师。因此,您不能将学校情况描述为组件的 JOIN。 (该关系是“所有(候选)键”。)

如果您描述默认值和异常(exception)情况,您可能能够用更少的数字来描述情况。

PS参见this answer重新默认以及特殊的添加和删除。

<小时/>

(对您的问题的早期编辑产生的解决方案的一些猜测如下。我使用了一些新的表名称,尽管一些具有新名称的表可能最终会成为您的一些旧表。我使用最少的 ID。)

也许您只需要两个实体表和一个多对多表:

teacher "TEACHER identifies a teacher named NAME"
classroom "CLASSROOM identifies a classroom"
has_access "teacher TEACHER has access to classroom CLASSROOM"
    FK (TEACHER) references teacher
    FK (CLASSROOM) references classroom

还要记录实际允许的访问:

is_accessing "teacher TEACHER is accessing classroom CLASSROOM"
    FK (TEACHER, CLASSROOM) references teacher_access

另一方面,“访问权”可能是 1:1 的一组教室,并且拥有访问权意味着允许访问这些房间。这种情况可以记录在上面的数据库中。但它可以按如下方式组织得更少冗余。

teacher "TEACHER identifies a teacher named NAME"
classroom "CLASSROOM identifies a classroom"
access "ACCESS identifies an access"

access_classroom "access ACCESS acesses classroom CLASSROOM"
    FK (ACCESS) references access
    FK (CLASSROOM) references classroom
teacher_access "teacher TEACHER has access ACCESS"
    FK (TEACHER) references teacher
    FK (ACCESS) references access

现在

has_access "teacher TEACHER has access to classroom CLASSROOM"

select TEACHER, CLASSROOM
from teacher_access natural join access_classroom

还要记录实际允许的访问:

is_accessing "teacher TEACHER is accessing classroom CLASSROOM"

那么我们仍然希望:

    FK (TEACHER, CLASSROOM) references has_access

但在大多数 DBMS 中,这不能以声明方式强制执行。

关于mysql - 2个多对多关系的数据库建模,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35293168/

相关文章:

django - 将 Django 模型/表拆分为两个模型/表是否有性能优势?

MySQL - 从平面表移动到第一范式

php - 如何使用 PHP 将动态文本框保存到数据库

php - 为什么即使数据库为空,图像也会显示损坏?

php - 解析错误 : syntax error, 意外 '$_GET' (T_VARIABLE)

c# - 最小起订量和 SqlConnection?

database - Cassandra cql 相当于 sql 中的 over()

sql - 使用联接和匹配特定列执行 SQL 更新

mysql - SQL查询性能-单条记录,按非索引列过滤,按索引列排序,记录在排序记录的序列中接近

php - 开发多语言站点的任何想法 - SEO、php、mysql