Mysql 多对多关系数据库

Mysql 多对多关系数据库,mysql,database,Mysql,Database,我知道mysql在技术上不支持多对多。我们应该创建一个桥接表。但就我而言,我仍然对此感到困惑 当许多用户可以有许多朋友时,两个表(或更多)是什么样子?把它想象成社交网络应用 user ===== id name friend ===== id name 我很困惑,不知道如何链接它们,因为在朋友表中,id也可以是用户id。问题是这种关系是否一定是对称的,也就是说,如果Alice是Bob的朋友,那么Bob也是Alice的朋友 通常情况下,这是不正确的,因此您需要一张这样的桌子,而不是您的桌友:

我知道mysql在技术上不支持多对多。我们应该创建一个桥接表。但就我而言,我仍然对此感到困惑

当许多用户可以有许多朋友时,两个表(或更多)是什么样子?把它想象成社交网络应用

user
=====
id
name

friend
=====
id
name

我很困惑,不知道如何链接它们,因为在朋友表中,id也可以是用户id。

问题是这种关系是否一定是对称的,也就是说,如果Alice是Bob的朋友,那么Bob也是Alice的朋友

通常情况下,这是不正确的,因此您需要一张这样的桌子,而不是您的桌友:

friends
======
user_id
friend_id
其中user_id和friend_id都指向表用户(即它们是外键约束)


如果关系是对称的,我认为上述方法仍然有效,您可以始终插入(或删除)两条记录,或者始终需要检查两列。

制作第三个“映射”表是最佳做法

用户id和用户朋友id都是该用户表的外键

这允许最有效的查询,如“给我所有id=17的朋友”,并且,如果朋友连接是单向的(例如,友谊请求),您可以通过另一种方式“向我显示id=17的朋友/希望成为朋友的人”


社交网络很可能会使用一种叫做图形数据库的东西。关系数据库很棒,除非您需要扩展。在某种程度上,使用传统数据库(如MySQL)在10万台机器上分割数据是可行的

这很好,但是您如何检查
friend\u user\u id
是否将
user\u id
作为他们的朋友?您需要有两个数据集,如
1,2
2,1
,才能构建该数据集。因此,引入一些业务规则是有意义的,比如“友谊关系始终是全方位的”,“用户id始终是较低的整数,
朋友用户id
始终是较高的整数”。实际上,您不需要这样做。如果你想找到一个id的所有友谊关系,你可以这样做,我将你的WHERE子句设置为捕获这两个:从m2m_user_friend中选择*from m2m_user_friend,其中user_id=17或friend_user_id=17好吧,是这样,但效率不高。另一方面,如果插入新关系,则始终需要同时检查这两个关系,以确保没有它们。但是,如果定义较低的id始终位于第一位,则在插入新行之前,不需要在两个方向上进行检查。在你的应用程序中或作为存储过程中,你可以先将较低的id放在第一位,然后再依赖主键的唯一性。你可以这样做,不管它的性能如何。。我怀疑。CPU周期成本很低,对缓存线的内存访问成本很高。但在97%的情况下,它将在一个缓存线中同时获取两列。但是,这样的优化会让其他开发人员更加困难——如果他们以后不得不更改项目中的某些内容,并且不知道较低id的内容。我至少会给这个列起一个像lower_user_id这样的名字。但是,你怎么选择呢?每个用户将有两个部分:一个是高ID,一个是低ID。我想你错过了。
user
=====
id
name

m2m_user_friend
=====
user_id
friend_user_id