设计此数据库的正确方法是什么?
以下是我设置表格的方法:
我在一个名为教师的桌子和一个叫做乐器的桌子之间有很多关系。然后我有一个连接两者的桥牌桌。我想将另一个表与BRIDGE表关联起来。意思是乐器/教师组合。该表将有3行指定教师可以教授的教学级别(即初级,中级,高级)。好像我应该设置桥表有teacher_id,instrument_id和level_id,但我不知道这是否是传统的方法。
我正在使用mysql和cakephp,我在文档中没有找到关于在桥表中有一个额外字段的HABTM关联的任何内容。只是想确保我正确地做到了。
答案 0 :(得分:5)
+1为Matt Fenwick。我想补充一点,你想对外键约束要小心一点。您基本上有两个选项,根据您选择的主键,这两个选项最终看起来非常相似。
选项一:忘记TEACHER
和INSTRUMENT
之间的简单交集,并将其替换为包含teacher_id
,instrument_id
的复杂交叉点和level_id
。这三列中的所有三列都是此交集表的(复合)主键。在此选项中,您在teacher_id
和instrument_id
(以及level_id
上定义了外键约束,如果这实际上是LEVEL
表的外键而不仅仅是整数或字符串代码)。
选项二:保持TEACHER
和INSTRUMENT
之间的简单交集(让我们称之为TEACHER_INSTRUMENT
,即使这是无法想象的)并添加一个子子表,定义可以教授的级别。这个子子表(我们称之为SKILL
)有一个level_id
和一个TEACHER_INSTRUMENT
的外键。如果TEACHER_INSTRUMENT
的主键是teacher_id
和instrument_id
的组合,则SKILL
表将具有与选项1中相同的三列。是什么让这个选项不同? 来自 SKILL
的外键约束必须是交集表,而不是 TEACHER
和 {{1} }。
为什么这很重要?如果选择第一选项,则可能需要一些额外的查询逻辑来获得完全填充的技能网格,因为没有参照完整性约束,您可以定义将确保为每个教师/乐器组合填充所有技能水平。
另一方面,如果你选择第二选项,你就可以分清谁可以使用什么以及如何教它。
您要避免的是让一个表只包含教师/乐器关系,然后是第二个(独立地)重复该关系但增加技能等级细节的表。如果你这样做,那么你冒着这两件事不同步的风险。
答案 1 :(得分:3)
如果这是您的数据所要求的,并且听起来像它,那么就去吧。
基本上,正如您所指出的,您将拥有一个由三部分组成的密钥:
这意味着教师可以在初级和高级教授吉他,在初级和初级阶段教钢琴,另一位老师可以在三个级别教钢琴,初学者用双簧管教学......听起来不错。
顺便提一下,桥接表也称为intersect
或intersection
表。