Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/67.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mysql 数据库设计——多对多表——如何最好地表示_Mysql_Sql - Fatal编程技术网

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中,连接表也称为直通表。