Я пытаюсь создать очень простую таблицу, в которой хранятся данные друзей в сообществе.
Поэтому я храню userId
2 друзей соответственно.
Цель
Пользователь хочет загрузить свой список друзей.
t_friends Опция 1:
запрос
SELECT * FROM t_friend WHRE user_id = 10
10
это ток userId
пользователя, который ищет свой список друзей и у него есть 1 друг 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
У меня есть ощущение, что есть более разумный способ решить это. У вас есть опыт работы с этой структурой?
Спасибо
Я думаю, что это единственный способ хранить данные об отношениях. Когда вы сохраняете отношения, попытайтесь сохранить минимальное значение в качестве userId и максимальное значение в качестве FriendId. сделайте оба значения совершенно уникальными, и вы не получите повторяющихся значений. При поиске пользователей используйте что-то вроде ниже
SELECT * FROM t_friend WHERE user_id=10 OR friend_id=10
Добавить поле Friends_key:
ALTER TABLE t_friend ADD Friends_key десятичный (22,11);
СОЗДАЙТЕ УНИКАЛЬНЫЙ ИНДЕКС Friends_key_unique ON t_friend (Friends_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);
}
Вы можете использовать следующий запрос, который сначала проверяет, не является ли ваш пользователь другом другого:
INSERT INTO t_friend (userId, friendId)
SELECT 10, 20
WHERE NOT EXISTS ( SELECT userId
FROM t_friend
WHERE userId = 20
AND friendId = 10)
Благодаря этой (французской) теме о проверке избыточности Вот.