我不知道下面我的想法是否适用:
我有两张桌子,分别是A和B.
表A中的每一行都可以与表B的零行或多行相关联。 表B中的每一行也可以与表A的零行或多行相关联。
表A包含(其中)2列AId(作为主键)和BId(作为外键)。 表B还包含(其中包括)2列BId(作为主键)和AId(作为外键)。
还为DB和模型类中的每个外键关系设置了级联删除规则。 这意味着删除一行A也会删除与之关联的B 或的行,删除一行B将删除与之关联的A行。
这种情况几乎可以实现吗?
答案 0 :(得分:7)
不,如果您遵循正常形式则不行。
多对多关系是需要交叉表的标志。
更多信息:
所以这是一个例子。问题标记。标签可以包含多个问题,而问题可以包含多个标签。这是一个多对多的现实。您可以在Question实体的Tag列中放入多个tagIds条目。但是你这样做会失去很多。
您将无法保持诚信,因为无论标记表和问号标记列中是否存在标记都非常难以维护。
这也违反了正常形式,因为单个列不能有多个值。
您也无法轻松加入该列,因为它中包含多个值。
答案 1 :(得分:2)
您需要的是一个联接表。因此,您有一个a
和b
表,每个表都有一个主键。然后创建一个只有2列的ab
表。两者都是外键。一个进入a
表,另一个进入b
表。
Google for"数据库规范化"。你会发现很多例子。
答案 2 :(得分:2)
这是可能的,但你绝对不希望这样做。
您可以在其中一个表中使用逗号分隔的标识字符串。从那张桌子到另一张桌子查找价值当然是一个很大的麻烦。从另一张表中查找值是一场噩梦。
使用此方法的级联触发器当然是不可能的。通过使更新触发器完成工作可能是可能的,但是它的性能会非常糟糕,以至于没有意义。
为了有效地做到这一点,你绝对需要另一张关系表。
答案 3 :(得分:2)
我假设您所指的“任意 - 任何”关系'many-to-many'。
您在帖子中描述的内容并非多对多关系。你所描述的是两个独立的一对多关系。
通过TableB中的AId列,您具有从TableA到TableB的一对多关系。并且您通过TableA中的BId列从TableB到TableA有另一个一对多关系。在相反方向上具有两个一对多关系与拥有多对多关系不是一回事。以Stefan的标记示例为例,考虑三个查询(QId1,QId2和QId3)和三个标记(TId1,TId2和TId3)。尝试表示所有QId1,QId2和QId3都标记有所有TId1,TId2和TId3。你会意识到你不能,因为你试图只在6个可用的“外键”字段中表达9种关系。一个真正的多对多关系需要在两个大小为M和N的表之间达到MxN'链接',而你的设计允许M + N(这并不奇怪,因为你的设计是1到1之一的M链接 - 多个关系和另一个1对多关系中的另外N个链接。)