2010-05-26 123 views
10

存储用户关系的最佳方式是什么?友谊,必须是双向的(你是我的朋友,因此我是你的朋友)在rel。数据库,例如MySQL的?在关系数据库中存储1:1用户关系的最佳方式

我能想到的方法有两种:

  1. 每当用户朋友的其他用户,我想补充两行到数据库,行A由后面的UID的innitiating用户的用户ID下一列中的接受用户。行B将是相反的。
  2. 您只能添加一行,UID(启动用户),后跟UID(接受用户);然后在试图弄清用户1是否是用户2的朋友时,只需在两列中进行搜索。

肯定还有更好的吗?

+0

听起来像你有设计权。你引用的是两个表之间的关联,以便在每个表和关联表之间创建0..1或更多。最终它所俘虏的是多对多。但我必须说出你的权利,以这种方式处理它。 – 2010-05-26 01:07:02

回答

8

我将有一个链接表的朋友,或任何,2列都是PK的,并且都是FK的用户表。

两列都是UID,每个朋友关系(A,B和B,A)都有两行。只要两列都是PK的,它应该仍然是正常的格式(尽管其他人可以自由纠正我)

它的查询稍微复杂一点,但没有任何东西不能被抽象掉存储过程或一些业务逻辑,它的格式通常很好。

+5

请记住,在MySQL中默认引擎MyISAM不支持外键,请切换到InnoDB。 – 2010-05-26 01:15:36

+0

确实如此,但是如果你绝对不得不使用MyISAM,那么你可以逃避这些不是真正的FK,但它可能会影响你的数据完整性和规范化,坚持使用InnoDB – 2010-05-26 01:27:54

+2

我会使用这个系统以及它大大简化用于查找朋友的选择查询,尤其是当您需要加入这张表时。但是,您应该使用事务和存储过程来确保两行总是一起插入和删除(您不**不希望意外删除两行中的一行)。 – 2010-05-26 01:34:19

3

使用双行,虽然它创建额外的数据,将大大简化您的查询,并允许您聪明地索引。我还记得在Twitter的自定义MySQL解决方案中看到的信息,其中他们使用额外的字段(基本上是朋友#)来执行自动限制和分页。它看起来相当平稳: https://blog.twitter.com/2010/introducing-flockdb

-6

使用关键值存储区,例如Cassandra。

+0

该请求特别针对MySQL解决方案。 – ethanpil 2017-01-27 15:28:26

3

您可以检查哪两个user_id是最低的,并按特定顺序存储它们。通过这种方式,您不需要为两个友谊重复行,并且仍然保持简单的查询。

user_id_low | user_id_high

一个简单的查询来检查,如果你已经在与某人的朋友应该是:

<?php 
$my_id = 2999; 
$friend_id = 500; 

$lowest = min($my_id, $friend_id); 
$highest= max($my_id, $friend_id); 

query("SELECT * FROM friends WHERE user_id_low=$lowest AND user_id_high=$highest"); 
?> 

或者你可以用mysql

<?php 
query("SELECT * FROM friends WHERE user_id_low=LEAST($my_id, $friend_id) AND user_id_high=GREATEST($my_id, $friend_id)"); 
?> 

找到最低/ higest用户名和获得所有你的朋友编号为

<?php 

query("SELECT IF(user_id_low=$my_id,user_id_high,user_id_low) AS friend_id FROM friends WHERE $my_id IN (user_id_low, user_id_high)"); 

?> 
+0

看了半分钟后,只是觉得我会想出一个很好的理由,为什么不应该使用。但是,不,我没有。这不是一个糟糕的解决方案 - 实际上非常优雅:)实际上,这也支持一个系统,您可以安排一组例如100个朋友组,只需将它们全部放入asc/desc命令 – 2013-12-19 13:04:55