我有一个社交网站,你可以添加好友。它的工作方式是这样的:
然后我可以确定他们是否是朋友,以及他们是否已被接受。
但是,这肯定不是正确的方法。我现在非常不确定哪种方式可以更好,运行得更顺畅。
答案 0 :(得分:7)
真的没有正确或错误的方式,这是你决定使用的,在一天结束时它是你的代码,所以无论你选择什么,为你工作。
然而,你是完全正确的,进入两行将是一个非常沉重的开销,并使用额外的空间看似没有充分的理由。更简单的说,您可以在数据库中设置另一列:
user_1
| user_2
| accept_code
| accepted
user_1
请求将user_2
添加为朋友 - 您在数据库中设置accept_code
创建条目。设置数据库结构以将accepted
列设置为定义为 false。然后,当首次创建行时,用户当前不是朋友。
使用你的例子:bob请求fred作为朋友。你的数据库现在看起来像这样:
bob
| fred
| 123123
| false
当user_2
输入accept_code
时,请将accepted
更改为true。
bob
| fred
| 123123
| true
这样,一个查询将告诉您这两个用户是否是朋友,而不是两个查询,以查看您是否有两个匹配的数据库条目。
所以例如,鲍勃已经添加了弗雷德,乔和亚历克斯作为朋友,弗雷德和亚历克斯已经接受鲍勃作为朋友,但乔没有。你的数据库看起来像这样:
user_1
| user_2
| accept_code
| accepted
bob
| fred
| 123123
| true
bob
| joe
| 321321
| false
bob
| alex
| 789789
| true
因此,例如,一个假的选择也许,找到bob的所有朋友:
SELECT user_2 FROM relationships WHERE user_1="bob" AND accepted="true"
结果将是:
fred
alex
更新:
数据库结构:
user_1
| user_2
| accept_code
| accepted
bob
| fred
| 123
| true
bob
| alex
| 123
| true
bob
| joe
| 123
| false
ste
| bob
| 123
| true
joe
| alex
| 123
| true
选择声明:
SELECT * FROM relationships WHERE accepted = 'true' AND (user_1 = 'current_user' OR user_2 = 'current_user');
示例1 - bob登录,他已经请求了朋友并被邀请为朋友:
SELECT * FROM relationships WHERE accepted = 'true' AND (user_1 = 'bob' OR user_2 = 'bob');
结果:
bob
| fred
| 123
| accepted
bob
| alex
| 123
| accepted
ste
| bob
| 123
| accepted
示例2 - alex登录,他从未请求和朋友,但已被要求作为朋友:
SELECT * FROM relationships WHERE accepted = 'true' AND (user_1 = 'alex' OR user_2 = 'alex');
结果:
bob
| alex
| 123
| accepted
joe
| alex
| 123
| accepted
示例3 - joe登录后,他已经请了一位朋友并拒绝了一位朋友:
SELECT * FROM relationships WHERE accepted = 'true' AND (user_1 = 'joe' OR user_2 = 'joe');
结果:
joe
| alex
| 123
| accepted
答案 1 :(得分:6)
社交网络数据库关系可能会变得非常复杂,尤其是当流量扩大并请求涌入时。有很多数据可以从Facebook等开发者博客中的主要来源获得,他们如何修改和调整他们的系统他们的流量增加了。
没有任何一种正确的方法可以创建关系 - 这取决于你的代码结构 - 但是,据说做两个查询以创建一个简单的一对一关系并复制数据被正确地假设为不必要的额外高架。
您可以使用两个用户的ID创建一个简单的联结表,一个字段包含发起请求的字段(用户的int主键),另一个字段包含接收批准请求的字段(也是int主键。你可以有另一个状态int字段,其数值对应于关系的状态。
你应该总是使用数字键来表示你的用户身份 - 你永远不会知道有多少'John会加入!确保您甚至只有一个简单的“用户”表,其中包含唯一键的UserID。
UserID|Name
1 Frank
2 John
这当然可以包含其他信息,姓氏,地点,性别,最喜欢的西尔维斯特史泰龙电影等。
可以在具有以下结构的单独关系表中创建关系...因此,当Frank(id 1)请求John(id 2)时,我们最终得到这样的行。
RelationshipID|RequestedBy|Receipient|RequestStatus|ConfirmationCode
(primary key) 1 2 0 (however you format your url strings)
然后,您可以拥有所有关系的主键。每个链接都是可识别的。
另外,我个人会集成另一个表来定义状态变量。
StatusIdentifier|StatusDefinition
0 Requested but not yet approved
-1 Requested and denied (mark for deletion)
1 Requested and approved (active friendship)
这样你可以扩展程序中的关系类型,如果你想要更多,例如friended然后删除,阻止等。在我部署的大多数应用程序中,这种数据是XML的一个很好的候选者,但把它扔进数据库并没有错。收件人的响应必须获取RelationshipID,然后更新此状态值。
在关系表上添加更新的时间戳也是个好主意。
使用此结构,您可以使用用户表中的主要ID轻松查询所有用户的朋友。让Franks成阵:
$sql = 'SELECT Recipient FROM FriendRelationships WHERE RequestedBy = 1 AND RequestStatus = 1';
这将获取Frank的所有活动好友用户ID,因为他是请求者(1),我们限制已经收件人批准的请求。
答案 2 :(得分:-1)
嗨,你可以试试这个逻辑。
让我们说bob希望将fred添加为朋友。
bob send fred加为好友
动作:将数据库查找表作为朋友:[bob] [fred] [隐藏 - 仅在bob接受时才显示]
fred在验证后接受请求 行动:制作[hide] ---> [可见]
现在你与用户和朋友有关系。[查找表中的每一行都是朋友]
希望这会有所帮助