Database design 好友列表:关系数据库表设计
因此,好友列表的现代概念:Database design 好友列表:关系数据库表设计,database-design,relational-database,jointable,Database Design,Relational Database,Jointable,因此,好友列表的现代概念: 假设我们有一张名为Person的桌子。现在,这个人需要有很多好友(其中每个好友都在Person类中)。构造关系最明显的方法是通过联接表。 i、 e 但是,当用户想要查看好友列表时,程序必须检查“person1_id”和“person2_id”列才能找到他们的所有好友 这是实现此类表的适当方法,还是最好添加两次记录。。i、 e buddyID person1_id person2_id 0 1 2 1 2
假设我们有一张名为Person的桌子。现在,这个人需要有很多好友(其中每个好友都在Person类中)。构造关系最明显的方法是通过联接表。 i、 e 但是,当用户想要查看好友列表时,程序必须检查“person1_id”和“person2_id”列才能找到他们的所有好友 这是实现此类表的适当方法,还是最好添加两次记录。。i、 e
buddyID person1_id person2_id
0 1 2
1 2 1
因此,只需搜索一列
提前感谢。这里有几种可能的情况 首先,您需要确定伙伴关系是否可以是一种方式。如果B不是A的好友,A可以成为B的好友吗?我想不会,但这是值得明确的
常识会建议你查询更多而不是更新关系。因此,请为此优化您的数据。创建好友关系时,创建两个recrods:a到B和B到a。这将使查询变得简单。所以,是的,按照您已经考虑过的两条记录进行处理。这是一个多对多关系,需要一个关系表
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表将为每个人包含一行。它将包含任何关于好友的数据,因为这将使它非规范化。相反,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表示卡拉不认为乔治是好友。这使事情非常干净,避免了数据异常。您可以调整关系,而无需处理人员数据。此外,您还可以在外键上定义一个delete cascades规则,以便删除Person将自动为您删除所有关联的关系。相反,您可能希望防止这种情况,在这种情况下,您可以在外键上指定restrict(默认值),以防止删除仍定义了关系的人员
查询也很容易: 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。虽然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'
对这很有道理。我应该考虑一下。谢谢,谢谢你的详细回答。这两个都非常有用。在一个普通的MySql盒上,如果有人有20000个好友,并且想在<1秒钟内把整个列表拉到那里,这是一个可用的设计吗?
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'
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'