继续这个问题
在我的web应用中,我想允许用户添加朋友,就像facebook一样,在我之前的问题中,我最终决定拥有@yiding说的数据库结构:
我将使这个关系反规范化,使它是对称的。也就是说,如果1和2是朋友,我将有两行(1,2)和(2,1)。
缺点是它的大小是原来的两倍,你必须做2在建立和破坏友谊时写作。优点是你的读查询更简单。这可能是一种很好的权衡因为你大部分时间都在阅读而不是写作。
这有一个额外的好处,如果你最终不再需要一个数据库和决定做用户分片时,不必遍历每隔一个db碎片找出一个人的朋友是谁。
那么,现在如果用户1加用户2,用户5加用户2,像这样的东西将被写入db:
ROW_ID USER_ID FRIEND_ID STATUS
1 1 2 0
2 2 1 0
3 5 2 0
4 2 5 0
如您所见,我们首先插入"REQUEST SENDER"行,现在假设用户5
登录了,我们想向他显示友情请求,这是我的查询:
$check_requests = mysql_query("SELECT * FROM friends_tbl WHERE FRIEND_ID = '5'");
上面的查询,将获取ROW_ID = 4,这意味着上面的查询告诉我们用户2添加了5,但他没有,实际上是用户5添加了用户2,所以这里我们不应该显示用户5的任何友谊请求,而需要显示用户2的友谊请求。
我应该如何正确检查这个?
编辑后的回答
你的SQL查询应该是这样的:
SELECT USER_ID, FRIEND_ID FROM friends_tbl WHERE FRIEND_ID = '5' OR USER_ID = '5'
那么您必须以这种方式解析您的结果。假设你有一个这样的php数组:
$result = array(
0 => array(
'USER_ID' => 5,
'FRIEND_ID' => 2
),
1 => array(
'USER_ID' => 2,
'FRIEND_ID' => 5
)
2 => array(
'USER_ID' => 5,
'FRIEND_ID' => 8
),
3 => array(
'USER_ID' => 8,
'FRIEND_ID' => 5
)
)
你只需要得到偶数行:
$result_final = array();
for($i = 0; $i < count($result); $i++) {
if($i % 2 == 0) $result_final[] = $result[$i];
}
那么你将得到一个像这样的数组:
$result = array(
0 => array(
'USER_ID' => 5,
'FRIEND_ID' => 2
),
1 => array(
'USER_ID' => 5,
'FRIEND_ID' => 8
)
)
替代方法:使您的SQL看起来像这样:
SELECT FRIEND_ID FROM friends_tbl WHERE USER_ID = '5'
。
友情查询通知应该放在类似邮件收件箱的地方。你所描述的关系是指友谊关系,而不是事件发生的事实本身。您应该考虑创建关系来保存通知,并在friends_tbl
您需要保存一个临时表(或固定表—用于数据挖掘),其中包含从一个用户向另一个用户发出的所有请求,例如:
表:friendRequest
inviterId inviteeId status tstamp
2 5 0 NOW()
5 8 0 NOW()
假设0是未经批准的。
那么您将查询所有挂起的请求
SELECT * FROM friendRequest WHERE invitee_id = :currentLoggedUserId AND status = 0
一旦用户批准了一个用户,您将创建一个事务,描述这个新形成的关系并更新friendRequests表
你也可以这样查询非对称关系,用户有很多追随者,通过寻找非相互的友谊。