Mysql 数据库设计——多对多表——如何最好地表示
我需要代表教师和他们所教科目之间的多对多关系 对于实施,我想到了两个策略:Mysql 数据库设计——多对多表——如何最好地表示,mysql,sql,Mysql,Sql,我需要代表教师和他们所教科目之间的多对多关系 对于实施,我想到了两个策略: teacher_name | subject_names bill math, english, science, french sally | chemistry, english, arts & crafts 我拒绝了这种策略,因为用逗号分隔的值查询字段似乎效率不高,特别是当我将为搜索引擎、迭代等提取字段时。。。尽管我当然愿意听到对这一策略的辩护 teacher_n
teacher_name | subject_names
bill math, english, science, french
sally | chemistry, english, arts & crafts
我拒绝了这种策略,因为用逗号分隔的值查询字段似乎效率不高,特别是当我将为搜索引擎、迭代等提取字段时。。。尽管我当然愿意听到对这一策略的辩护
teacher_name | subject_name
bill math
bill english
bill science
... ...
sally chemistry
sally english
... ...
我最初认为这是一个更好的主意,但当我查询有关老师的信息时,我得到的数据很难报告。i、 很好,我有5排鲍勃的主题,但不好的是,我还发现他住在主街123号和主街123号和主街123号。。。总的来说,我仍然认为这是一个更好的想法,但也许存在一个更好的想法
顺便说一句,我并没有真正使用教师姓名和学科名称来索引,我使用数字,但为了清晰起见,我用这种方式绘制了它您可以有一个科目表(id,学科名称),另一个教师表(id,教师名称)和另一个名为教师科目的表,教师id,学科id作为复合键。这是多对多关系的最推荐方法,因为它是标准化的。多对多关系最好使用第三个表来解决,该表称为映射关系的连接表。这里有一个更详细的解释,但基本上 新表将包含两列外键;一列中教师的唯一ID(教师表的主键)和另一列中的subjects唯一ID(subjects表的主键)(…当然还有连接表自身唯一ID的列) 说这是你的教师表:
----------------------------
| ID | Name | Last_Name |
----------------------------
| 0001 | JOHN | STEPHENS |
----------------------------
| 0002 | BRUCE | WAYNE |
----------------------------
--------------------------------
| ID | Teacher_ID | Subject_ID |
--------------------------------
| 01 | 0001 | 0101 |
--------------------------------
| 02 | 0001 | 0202 |
--------------------------------
| 03 | 0002 | 0101 |
--------------------------------
| 04 | 0002 | 0303 |
--------------------------------
这是你的主题表
-----------------------
| ID | Subject_name |
-----------------------
| 0101 | MATH |
-----------------------
| 0202 | BIOLOGY |
-----------------------
| 0303 | ENGLISH |
-----------------------
然后您需要一个这样的连接表:
教师主题链接表:
----------------------------
| ID | Name | Last_Name |
----------------------------
| 0001 | JOHN | STEPHENS |
----------------------------
| 0002 | BRUCE | WAYNE |
----------------------------
--------------------------------
| ID | Teacher_ID | Subject_ID |
--------------------------------
| 01 | 0001 | 0101 |
--------------------------------
| 02 | 0001 | 0202 |
--------------------------------
| 03 | 0002 | 0101 |
--------------------------------
| 04 | 0002 | 0303 |
--------------------------------
现在,无论何时,只要您需要获取教授数学的教师列表(subject_id 0101),您就可以简单地查询juction表;差不多
SELECT Teacher_ID FROM TeacherSubject_JunctionTable
WHERE Subject_ID = 0101;
或者反过来,如果你想得到老师教的科目。你的两种解决方案都打破了标准化策略 通常的方法是使用第三个联接表
teacher_ID | teacher_name | Other stuff about teachers
1 | bill | address, dob etc.
2 | sally | etc.
subject_ID | subject_name | Other stuff about teachers
1 | math | department, campus etc.
2 | english | etc.
teacher_ID | subject_ID | Other stuff about the relationship
1 | 4 | location etc.
1 | 2 | etc.
2 | 2 | etc.
2 | 1 | etc.
教师ID和科目ID在前两个表中是一个自动递增的int主键。
教师ID和科目ID是第三个课程的主键。至少,在尝试设计任何内容之前,您应该阅读基本的数据库概念和规范化。逗号分隔的字段在数据库中从来都不是一个好主意。这一切似乎都有道理,但我想知道在TeacherSubject\u JunctionTable中ID字段是用来做什么的。这个数字什么时候有用?很好的观点,你是绝对正确的——把它删掉没有问题(许多人选择这样做)。无论如何,我通常都喜欢有一个ID字段,因为我发现有一个简单的方法来引用一行很好,老实说,ID字段占用的磁盘空间量不太可能是一个问题。但连接表实际上主要是一个实现细节,而不是它本身的实体,因此(取决于您对数据库的喜爱程度)将其忽略是完全合理的做法。实际上,这主要是一个品味问题。虽然它不像连接表的实现那样“纯粹”,但有时可以添加关于两个元素之间关系的额外信息,在这一点上,我认为有一个ID字段是非常有用的。考虑一个表,<代码>销售> /代码>它可以被认为是一个JT,它描述了表<代码>项目和<代码>客户> /代码> -并且您可能想要添加一个<代码>时间戳<代码>字段,以显示该表何时被购买,并且可能有折扣百分比,谁知道。纯粹主义者可能不同意这仍然是一个JT,但基本概念保持不变。在Django中,连接表也称为直通表。