@coden55

Какую выбрать логику запросов к БД (задачка)?

Задачка такая: есть подобие соцсети с пользователями, которые заводят альбомы, в альбомы добавляют фотографии. Пользователь может выставить своему альбому уровень доступа для других пользователей: 1.альбом виден только мне (владельцу), 2.виден только друзьям, 3.виден только подписчикам (+друзья). Структура таблицы подписчиков предположительно будет состоять из двух колонок: from (ид подписчика) и to (ид на кого подписываются). Наличие в таблице двух обратных записей (подписаны друг на друга) означает, что пользователи - друзья.

Вопрос в том по какой логике составить запрос к БД чтобы он выдал список альбомов всех пользователей, к которым клиент имеет право доступа.
Я вижу 2 варианта:

1:
  • №1 Запросить список пользователей на которых подписан клиент
  • №2 Запросить список пользователей которые друзья с клиентом (использовать список №1)
  • №3 Запросить список альбомов пользователей из списка №1
  • Провести отбор, выдать результат используя 3 списка

Имхо сложный алгоритм, который будет сильно нагружать систему

2:
Формировать в БД дополнительную таблицу из двух колонок, которая хранит id пользователя и ид альбома который он может просматривать.
В эту таблицу вносятся изменения (добавляется/удаляется пара) в момент когда кто-либо из пользователей:
  • создает альбом - добавляет id альбома всем пользователям кто в текущий момент имеет право его смотреть
  • удаляет альбом - затирание id альбома у всех где он был
  • изменяет уровень доступа существующего альбома - 2 процедуры выше: удаление + создание
  • пользователь подписывается - получаем альбомы, добавляем в перечень
  • пользователь отписывается - затираем ид альбомов пользователя

Интуитивно мне кажется что это более правильный вариант. Однако есть риск что некоторые ключи будут теряться в бд из-за сбоев, и будет требоваться перестройка таблицы.

Кто что думает, может есть другой вариант?
  • Вопрос задан
  • 173 просмотра
Решения вопроса 1
effetto
@effetto
.Net разработчик
Конечно, дублирование информации в бд - не нормальный вариант. Но рекурсивный проход для SQL систем - тоже ненормальный вариант. Об этом на википедии даже статья есть: https://en.wikipedia.org/wiki/Hierarchical_and_rec...

Я решаю такую задачу одним из двух вариантов, как и Вы.

В первом варианте - это джойн самой же таблицы по вторичному ключу. Таким образом каждая запись имеет в результирующей таблице своего предка, что удобно для последующей неSQL обработки.

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

Другие варианты:

Еще я реализовывал рекурентный обход через хранимые функции, - это медленный вариант.

При разработке соцсети, я бы использовал второй вариант. Рекомендую реализовать оба и провести нагрузочное тестирование при больших объемах. А дальше выбрать на основе анализа данных после тестирования.
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
swanrnd
@swanrnd
Издатель HTML5 игр
В чем проблема?
1) получаем статус клиента. Список пользователей не надо получать, нужно лишь проверить на наличие в подписках и друзьях одного клиента.
2) получаем список альбомов.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы