как разрешения на просмотр обычно реализуются в реляционной базе данных? - PullRequest
4 голосов
/ 26 июня 2010

Какова стандартная идиома реляционной базы данных для установки разрешений для элементов?

Ответы должны быть общими;тем не менее, они должны быть в состоянии применить к примеру ниже.Все что угодно: добавление столбцов, добавление еще одной таблицы - независимо от того, насколько это хорошо работает.

Приложение / Пример

Предположим, база данных Twitter очень проста: у нас есть одна таблица User, котораясодержит логин и идентификатор пользователя;у нас есть таблица Tweet, которая содержит идентификатор твита, текст твита и идентификатор создателя;и у нас есть таблица Follower, которая содержит идентификатор человека, за которым следят, и последователя.

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

  • Все в Твиттере
  • Только текущие подписчики (которые, конечно, должны быть одобрены пользователем, хотя это не имеет значения) РЕДАКТИРОВАТЬ: Текущий, как в, я получил новый последователь, он видит это;Я удаляю подписчика, он перестает видеть его.
  • Конкретные подписчики (например, идентификатор пользователя 5, 10, 234 и 1)
  • Только владелец

В этих условиях, как лучше всего представлять разрешения на просмотр?Приоритеты по порядку: скорость поиска (вы хотите иметь возможность быстро выяснить, какие твиты отображать пользователю), скорость создания (вы не хотитечтобы опубликовать твит навсегда) и эффективное использование пространства (каждый раз, когда я публикую твит для всех в списке моих подписчиков, мне не нужно было добавлять строку для каждого подписчика, которого ядолжны к некоторому столу.)

1 Ответ

1 голос
/ 26 июня 2010

Похоже на типичное отношение «многие ко многим» - я не вижу каких-либо ограничений в том, что вы хотите, что позволило бы сэкономить пространство по сравнению с типичной идиомой реляционных БД для них, то есть таблицы с двумя столбцами (оба внешних ключи, один для пользователей и один для твитов) ... поскольку текущие подписчики могут и действительно изменяться, отправляя твит всем подписчикам, которые актуальны на момент публикации (я полагаю, это то, что вы имеете в виду?) означает означает, что добавление такого количества (очень коротких) строк в эту таблицу взаимосвязей (альтернатива сохранения истории наборов подписчиков с метками времени, чтобы вы могли восстановить, кто был подписчиком в любой заданный момент публикации твита, со временем определенно выглядит хуже и не существенно лучше в космосе).

Если, с другой стороны, вы хотите проверять подписчиков во время просмотра (а не во время публикации), то вы могли бы создать специальный идентификатор пользователя искусственно означает «все подписчики текущего пользователя» (точно так же, как у вас будет одно значение «все пользователи в Твиттере»); необходимый SQL, чтобы сделать поиск быстрым, в этом случае выглядит волосатым, но выполнимым (СОЮЗ или ИЛИ со «всеми твитами, за которые я являюсь последователем автора, а твит читается [искусственным идентификатором пользователя, представляющим] всех последователей» «). Я не буду углубляться в этот лабиринт SQL до тех пор, пока вы не подтвердите, что вы имеете в виду именно этот специфический смысл (а не простой, который кажется мне более естественным, но не позволяет любая экономия места на таблице отношений для действия «опубликовать твит всем подписчикам»).

Редактировать : ФП уточнил, что они означают подход, который я упоминаю во втором абзаце.

Тогда предположим, что userid является первичным ключом таблицы Users, таблица Tweets имеет первичный ключ tweetid и внешний ключ author для ИД пользователя каждого твита, Followers table - это типичная таблица отношений «многие ко многим» с двумя столбцами (оба внешних ключа в Users) follower и followee, а таблица Canread - не очень типичная «многие ко многим» таблица отношений, все еще с двумя столбцами - внешний ключ в Users - это столбец reader, внешний ключ в Tweets - это столбец tweet (phew ;-). Два специальных пользователя @everybody и @allfollowers определены с вышеуказанными значениями (так что публикация всем, всем подписчикам или «только мне») добавляет только одну строку к Canread - только выборочное размещение в определенном списке из N человек добавляет N строк).

Таким образом, SQL для набора идентификаторов твитов, которые пользователь @me может прочитать, я думаю, что-то вроде:

SELECT Tweets.tweetid 
  FROM Tweets
  JOIN Canread ON(Tweets.tweetid=Canread.tweet)
 WHERE Canread.reader IN (@me, @everybody)

UNION

SELECT Tweets.tweetid 
  FROM Tweets
  JOIN Canread ON(Tweets.tweetid=Canread.tweet)
  JOIN Followers ON(Tweets.author=Followers.followee)
 WHERE Canread.reader=@allfollowers
   AND Followers.follower=@me
...