我正在尝试设计一个非常简单的表格,用于存储社区中朋友的数据。
因此我分别存储了2个朋友的userId
。
目标
用户想要加载他/她的朋友列表。
t_friends 选项1:
查询
SELECT * FROM t_friend WHRE user_id = 10
10
是用户的当前userId
,正在寻找他的朋友列表,他有一个朋友userId(20)
这种方式userId (10)
找到了他的朋友(20)
但是如果userId(20)
正在寻找他的朋友呢?
该查询与userId
。
这引出了另一种包含冗余数据的设计:
t_friends 选项2:
userId (10)
现在加载:
SELECT * FROM t_friend WHRE user_id=10
类似于userId(20)
的查询将是:
SELECT * FROM t_friend WHRE user_id=20
但冗余怎么样?然后使用表格设计选项1引导我进入该查询:
SELECT * FROM t_friend WHERE user_id=10 OR friend_id=10
我觉得有一种更聪明的方法可以解决这个问题。你有这方面的经验吗?
由于
答案 0 :(得分:2)
我认为这是存储关系数据的唯一方法。存储关系时,尝试将min值存储为userId,将max值存储为friendId。使两个值完全唯一,您将不会获得任何重复值。当您搜索用户时,请使用以下内容
<span class="js-documentBox">6227_150510_0510175608II</span>
答案 1 :(得分:2)
添加字段friendship_key:
ALTER TABLE t_friend ADD friendship_key decimal(22,11);
CREATE UNIQUE INDEX friendship_key_unique ON t_friend(friendship_key);
和php部分:
$friends = [$userId, $friendId];
$key = min($friends).'.'.max($friends);
$q = "SELECT * FROM t_friend WHERE friendship_key = ".$key;
插入:
$friends = [$userId, $friendId];
$key = min($friends).'.'.max($friends);
$q = "INSERT INTO t_friend (friendship_key, userId, friendId) VALUES (".implode(',', [$key, $userId, $friendId]).")";
我没有使用VARCHAR作为友谊键,而是使用了十进制来最小化关系键的数据
为了简单起见,只需创建函数:
function insertFriendship($user1, $user2) {
$key = min([$user1, $user2]).'.'.max([$user1, $user2]);
$q = "INSERT INTO t_friend (friendship_key, userId, friendId) VALUES (".implode(',', [$key, $user1, $user2]).")";
mysql_query($q);
}
function getFriendsOf($user) {
$q = "SELECT * FROM t_friends WHERE ".$user." IN (userId, friendId)";
return mysql_query($q);
}
function areFriends($user1, $user2) {
$key = min([$user1, $user2]).'.'.max([$user1, $user2]);
$q = "SELECT 1 FROM t_friends WHERE friendship_key = ".$key." LIMIT 1";
$q = mysql_query($q);
return (mysql_num_rows($q)>0);
}
答案 2 :(得分:-1)
您可能需要使用以下查询来验证您的用户是否还不是另一个用户的朋友:
INSERT INTO t_friend (userId, friendId)
SELECT 10, 20
WHERE NOT EXISTS ( SELECT userId
FROM t_friend
WHERE userId = 20
AND friendId = 10)
感谢关于冗余验证的这个(法语)主题here。