2010-06-17 648 views
3

因此,好友列表的现代概念:
假设我们有一个名为Person的表。现在,该人需要有许多伙伴(其中每个伙伴也在人员课程中)。构建关系最明显的方法是通过连接表。 即好友列表:关系数据库表设计

buddyID person1_id person2_id 
0   1   2 
1   3   6 

但是,当用户希望看到自己的好友列表,程序会检查列“person1_id”和“person2_id”找到所有的哥们。

这是为了实现这种表的适当的方式,或将是更好的添加记录两次..即

buddyID person1_id person2_id 
0   1   2 
1   2   1 

所以只有一个列有要被搜索。

在此先感谢。

回答

2

这是一个多对多的关系,这是一个relator表是必需的。

create table Person (
    person_id int not null primary key, 
    username varchar(100) not null, 
    ... other_cols ... 
) 


create table Buddy (
    person_id1 int not null, 
    person_id2 int not null, 
    primary key (person_id1, person_id2), 
    foreign key (person_id1) reference Person (person_id), 
    foreign key (person_id2) reference Person (person_id) 
) 

因此Person表格显然会为每个Person包含1行。它将包含任何关于伙伴的数据,因为这会使其非规范化。相反,好友列表将包含人员之间的关系。

因此,可以说你在Person表是这样的:

person_id username 
1   George 
2   Henry 
3   Jody 
4   Cara 

亨利和卡拉是哥们,因为是乔治和卡拉这样:

person_id1 person_id2 
2   4 
1   4 

如果你需要把它这样的关系不隐含相互,那么你将需要添加额外的行,使其明确。所以现在可以说,亨利认为卡拉好友和卡拉同样认为亨利的好友,而乔治认为卡拉当哥们,但卡拉不与乔治回报:

person_id1 person_id2 
2   4 
4   2 
1   4 

失踪4 1表示卡拉不认为乔治是一个好友。这使得事情变得非常干净并且避免了数据异常。您可以调整关系而不会使用Person数据。您也可以在外键上定义删除级联规则,以便删除Person将自动删除所有关联关系。相反,您可能想要阻止这种情况,而不是在这种情况下,您可以在外键上指定restrict(默认值),以防止删除尚未定义关系的Person。

查询是太容易了:

多少哥们确实卡拉有(让我们假设对于好友列表关系是隐含的):

select count(*) from Person 
       join Buddy on person_id = person_id1 or person_id = person_id2 
where name = 'Cara' 

对于其中的关系是不是暗示它可能是更好的情况下改为重命名列如下:

person_id considers_as_buddy_id 
2   4 
4   2 
1   4 
4   3 

select count(*) from Person P 
       join Buddy B on P.person_id = B.person_id 
where name = 'Cara' 

这会返回卡拉认为有多少人是好友。在这种情况下2.虽然乔迪不认为卡拉是一个好友 - 所以要找出相互的关系,你会这样做:

select count(*) from Person P 
       join Buddy B on P.person_id = B.person_id and 
           B.considers_as_buddy_id = P.person_id 
where name = 'Cara' 
+0

谢谢你的详细答案。两者都非常有帮助。 – huntaub 2010-06-21 18:00:17

+0

在一个普通的MySql盒子上,如果有人拥有20,000个好友,并且想在<1秒内将所有列表拉出来,那么这是一个可用的设计吗? – 2011-11-29 15:45:49

5

这里有几种可能的情况。

首先,您需要确定伙伴关系是否可以是单向的。 B人不是A的哥们,人A可以成为人B的好友吗?我会假设没有,但值得明确。

常识会建议你查询更多比你更新关系。因此,为此优化您的数据。在创建好友关系时,创建两个recrods:A到B和B到A.这将使查询变得微不足道。所以,是的,如你已经考虑过的那样,用两个记录。

+0

是的。这很有意义。我应该想到这一点。谢谢。 – huntaub 2010-06-17 01:18:58