Лучший способ хранения отношений пользователя 1:1 в реляционной базе данных

Каков наилучший способ хранения пользовательских отношений, например. дружба, которая должна быть двунаправленной (вы мой друг, таким образом, я ваш друг) в rel. базы данных, например. MySql?

Я могу думать о двух путях:

  • Каждый раз, когда пользователь дружит с другим пользователем, я бы добавил две строки в базу данных, строку А, состоящую из идентификатора пользователя пользователя, который должен следовать за ним, а затем в следующем столбце идентификатор принимающего пользователя. Строка B будет обратной.
  • Вы добавили бы только одну строку, UID (инициирующий пользователь), за которой следует UID (принимающий пользователя); а затем просто выполните поиск по обоим столбцам, пытаясь выяснить, является ли пользователь 1 другом пользователя 2.

Неужели что-то лучше?

Ответ 1

У меня бы была таблица ссылок для друзей или что-то еще, причем 2 столбца были PK, и оба были FK в таблице User.

Оба столбца будут UID, и у вас будет две строки для отношения между друзьями (A, B и B, A). Пока оба столбца PK, он все равно должен быть в нормальном формате (хотя другие могут исправлять меня на этом)

Это немного более сложный запрос, но ничего, что не может быть абстрагировано хранимой процедурой или некоторой бизнес-логикой, и ее в нормальном формате, что обычно приятно иметь.

Ответ 2

Использование двойных строк при создании дополнительных данных значительно упростит ваши запросы и позволит вам быстро индексировать. Я также помню, что я видел информацию о настраиваемом MySQL MySQL, в котором они использовали дополнительное поле (в основном, friend #) для автоматического ограничения и подкачки. Это выглядит довольно гладко: https://blog.twitter.com/2010/introducing-flockdb

Ответ 3

Вы можете проверить, какой из двух user_id является самым низким, и сохранить их в определенном порядке. Таким образом вам не нужны двойные строки для одной дружбы и все еще сохраняют ваши запросы простыми.

user_id_low | user_id_high

Простой запрос для проверки того, что вы уже знакомы с кем-то, будет:

<?php
$my_id = 2999;
$friend_id = 500;

$lowest = min($my_id, $friend_id);
$highest= max($my_id, $friend_id);

query("SELECT * FROM friends WHERE user_id_low=$lowest AND user_id_high=$highest");
?>

Или вы можете найти самый низкий/самый высокий идентификатор пользователя, используя mysql

<?php
query("SELECT * FROM friends WHERE user_id_low=LEAST($my_id, $friend_id) AND user_id_high=GREATEST($my_id, $friend_id)");
?>

И чтобы получить все ваши друзья id

<?php

query("SELECT IF(user_id_low=$my_id,user_id_high,user_id_low) AS friend_id FROM friends WHERE $my_id IN (user_id_low, user_id_high)");

?>

Ответ 4

Используйте хранилище значений ключей, например, Cassandra.