它是在关系模型的最佳做法,以避免许多一对多的关系。正如你所看到的那样,工作台通常会补偿尝试这样做的用户。让我们用一个例子(或者检查tl; dr),其中有两个识别的实体;买家和硬件项目。有些人购买1件商品,其他人购买1件以上。问题是,同样的物品可以被很多人购买。所以买家表有A先生买钉子。简单到足以在一行中记录。但是,你看,他起身并获得另一件物品!我们如何证明他购买了另一件物品?
一种方法是在表中添加另一个属性(如“item_number_two”)。但是,他又得到了另一个!我们不能继续添加这样的属性。数据库的设计更多是为了垂直添加记录,而不是水平添加属性(以提供可视图片)。有一个更长的解释,但你应该阅读,或者可能可能会在阅读后找出它。
另一种方法是重新输入A先生的记录,然后在该列中输入另一个项目的ID,表明他购买了两件物品(从数据库的角度看,他不是“他”,而是两个不同的人!)。
更好的方法是创建一个由原始表中找到的唯一标识符组成的表(每个表只需一个)。这被称为中间表。原始表本身没有来自其他表的外键。
这是组合键的概念出现的地方。它意味着两个或多个候选键用于唯一标识一条记录,而不仅仅是一条。这是如何工作的:
Person Table:
| person_ID | person_Name |
| P0001 | Mr. A |
| P0002 | Mr. B |
| P0003 | Mr. C |
| P0004 | Mr. D |
Cat Table
| item_ID | cat_Name |
| I0001 | Nails |
| I0002 | Screws |
| I0003 | Hammers |
| I0004 | Power-Saw |
Intermediary table
| person_ID | item_ID |
| P0001 | I0001 |
| P0001 | I0002 |
| P0001 | I0003 | //Shows that person 1 bought more than one item
| P0002 | I0004 |
| P0002 | I0001 | //Shows that an item has been bought by more that one person
所以这个新表一个表中的记录匹配(通过使用一个主键)到另一个记录。唯一会重复的是两个ID之一。只要没有两个组合重复,就会创建一个独特的记录。如果映射到多对多关系的表格在输入记录时不可避免地浪费了数据库中的空间,因为必须创建相同数据的新记录以显示小的差异(不按比例添加实际值到空间)。另一个问题是,当进行查询时,它会导致更多的计算,浪费时间和空间。或者返回的结果可能是错误的...
编辑: 如果您有表A和B具有多对多关系,请执行以下操作作为替代方法。创建一张表C.从表A和B中取出主键并将它们放在表C中。在表C中它们都以主键和外键的形式存在。这意味着会创建以下关系。
| Table A |-----------<| Table C |>------------|Table B|
表A和B到C
示例查询链接:
SELECT C.itemID FROM A, C WHERE A.personID = P0001 AND A.personID = C.personID;
这个查询将返回由人与P0001的ID购买的物品的所有的ID。记录必须符合具有P0001的personID的条件,但所选记录必须在表C(中间表)中具有该匹配的ID。扩展查询可以从表B中获取项目名称.C中的每个属性都具有与表A或B中的键的值对应的记录值,这意味着可以运行查询来提取其他信息,表C中的值=表A/B中的值(取决于你想要的值)。
1.可以使用多对多关系的替代方案? – abhi
我提到的中间表。检查我的编辑。 –