所以,好友列表的现代概念:
假设我们有一个名为Person的表.现在,那个人需要有很多好友(其中每个好友也属于人类).构建关系最明显的方法是通过连接表.
即
假设我们有一个名为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
因此只需要搜索一列.
提前致谢.
解决方法
这是一个多对多的关系,这需要一个关系表.
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行.它将包含关于伙伴的任何数据,因为它会使其非规范化.相反,Buddy表将包含人员之间的关系.
所以假设你在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.
查询也很容易:
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'