2

因此,好友列表的现代概念:
假设我们有一个名为 Person 的表。现在,那个 Person 需要有很多好友(其中每个好友也在 person 类中)。构建关系最明显的方法是通过连接表。IE

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

所以只需要搜索一列。

提前致谢。

4

2 回答 2

5

这里有几种可能的情况。

首先,您需要确定好友关系是否可以是一种方式。如果 B 不是 A 的好友,A 是否可以成为 B 的好友?我认为不是,但值得明确。

常识会建议您查询比更新关系更多。因此,请为此优化您的数据。创建好友关系时,创建两个记录:A 到 B 和 B 到 A。这将使查询变得微不足道。所以,是的,按照您已经考虑过的两条记录一起去。

于 2010-06-17T01:14:00.190 回答
2

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

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 表明 Cara 不认为 George 是好友。这使事情变得非常干净并避免了数据异常。您可以调整关系而无需处理 Person 数据。您还可以在外键上定义删除级联规则,以便删除 Person 会自动为您删除所有关联关系。相反,您可能希望阻止这种情况,在这种情况下,您可以在外键上指定限制(默认值),以防止删除仍定义关系的 Person。

查询也很简单:

Cara 有多少好友(假设好友列表的关系是隐含的):

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'

这将返回 Cara 将多少人视为好友。在这种情况下 2. 虽然 Jody 不认为 Cara 是好友 - 所以要找出相互关系,您可以这样做:

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'
于 2010-06-17T01:37:57.357 回答