ryr*_*yan 8 mysql database-design
我有一个社交网站,你可以添加好友.它的工作方式是这样的:
然后,我可以确定他们是否是朋友,以及他们是否被接受.
但是,这肯定不是正确的方法.我现在非常不确定哪种方式可以更好,运行更顺畅.
实际上没有正确或错误的方式,它是您决定使用的,在一天结束时它是您的代码,所以无论您选择什么并为您工作.
但是,你是完全正确的,进入两行将是一个非常沉重的开销,并使用额外的空间看似没有充分的理由.更简单地说,您可以在数据库中设置另一列:
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
所以,例如,一个假的选择也许,找到所有朋友的鲍勃:
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 - 亚历克斯登录,他从未要求和朋友,但已被要求作为朋友:
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
社交网络数据库关系可能会变得非常复杂,特别是当流量扩大并要求涌入时.有很多数据可以从Facebook等开发者博客中的主要来源获得,他们如何修改和调整他们的系统以扩展为他们的交通量增加.
没有任何一种正确的方法来创建关系 - 这取决于您的代码结构 - 但是,据说执行两个查询以创建简单的一对一关系并复制数据被正确地假设为不必要的额外开销.
您可以使用两个用户的ID创建一个简单的联结表,一个字段包含发起请求的字段(用户的int主键),另一个字段包含接收批准请求的字段(也是int主键.)您可以有另一个状态int字段,其数值对应于关系的状态.
你应该总是使用数字键来表示你的用户身份 - 你永远不知道有多少'John会加入!确保您甚至只有一个简单的"用户"表,其中UserID是唯一键.
UserID|Name
1 Frank
2 John
Run Code Online (Sandbox Code Playgroud)
这当然可以包含其他信息,姓氏,位置,性别,最喜欢的西尔维斯特史泰龙电影等.
可以在具有以下结构的单独关系表中创建关系......因此,当Frank(id 1)请求John(id 2)时,我们最终得到这样的行.
RelationshipID|RequestedBy|Receipient|RequestStatus|ConfirmationCode
(primary key) 1 2 0 (however you format your url strings)
Run Code Online (Sandbox Code Playgroud)
然后,您可以拥有所有关系的主键.每个链接都是可识别的.
另外,我个人会集成另一个表来定义状态变量.
StatusIdentifier|StatusDefinition
0 Requested but not yet approved
-1 Requested and denied (mark for deletion)
1 Requested and approved (active friendship)
Run Code Online (Sandbox Code Playgroud)
这样你可以扩展程序中的关系类型,如果你想要更多,例如friended然后删除,阻止等.在我部署的大多数应用程序中,这种数据是XML的一个很好的候选者,但是有将它扔进数据库没有错.收件人的响应必须获取RelationshipID,然后更新此状态值.
在关系表上添加更新的时间戳也是一个好主意.
使用此结构,您可以使用用户表中的主要ID轻松查询所有用户的朋友.让弗兰克斯成阵:
$sql = 'SELECT Recipient FROM FriendRelationships WHERE RequestedBy = 1 AND RequestStatus = 1';
Run Code Online (Sandbox Code Playgroud)
这将获得Frank的所有活动好友用户ID,因为他是请求者(1)并且我们限制已经被收件人批准的请求.
| 归档时间: |
|
| 查看次数: |
5476 次 |
| 最近记录: |