По моему опыту, реальный вопрос в основном сводится к тому, произойдет ли какое-либо ограничение пользовательского ограничения доступа.
Предположим, например, что вы разрабатываете схемусообщество, и вы позволяете пользователям переключать видимость своего профиля.
Один из вариантов - придерживаться флага общего / частного профиля и придерживаться широких преимущественных проверок разрешений: 'users.view' (просматривает общедоступных пользователей) против, скажем, 'users.view_all' (просматривает всех пользователей для модераторов).
Другой вариант включает более тонкие разрешения, вы можете захотеть, чтобы они могли настраивать вещи, чтобы они могли создавать сами себя (а) видны всем, (б) видны их избранным друзьям, (в) полностью сохранены в тайне и, возможно, (г) доступны для просмотра всем, кроме их выбранных бузо.В этом случае вам нужно хранить данные, относящиеся к владельцу / доступу, для отдельных строк, и вам нужно будет тщательно абстрагировать некоторые из этих вещей, чтобы избежать материализации транзитивного замыкания плотного ориентированного графа.
При любом подходе я обнаружил, что дополнительная сложность в редактировании / назначении ролей компенсируется получающейся в результате легкостью / гибкостью при назначении разрешений для отдельных фрагментов данных, и что следующее работает лучше всего:
- Пользователи могут иметь несколько ролей
- Роли и разрешения, объединенные в одной таблице с флагом, позволяющим различать их (полезно при редактировании ролей / разрешений)
- Роли могут назначать другиеролям, а также ролям и разрешениям можно назначать разрешения (но разрешения не могут назначать роли) из одной и той же таблицы.
Полученный ориентированный граф затем можно получить в двух запросах, построенных раз и навсегда вразумное количество времени, используя тот язык, который вы используете, и кешируется в Memcache или Similar для последующего использования.
Оттуда получение прав пользователя - это проверка его ролей и их обработка с использованием графа разрешений для получения окончательных разрешений.Проверьте разрешения, убедившись, что пользователь имеет указанную роль / разрешение или нет.И затем запустите ваш запрос / выдайте ошибку, основанную на этой проверке разрешений.
Вы можете расширить проверку для отдельных узлов (т. Е. check_perms($user, 'users.edit', $node)
для "можно редактировать этот узел" против check_perms($user, 'users.edit')
для "может редактироватьузел "), если вам нужно, и у вас будет что-то очень гибкое / простое в использовании для конечных пользователей.
Как следует из первого примера, опасайтесь слишком сильно ориентироваться на разрешения на уровне строк.Узкое место в производительности меньше при проверке разрешений отдельного узла, чем при получении списка допустимых узлов (т. Е. Только тех, которые пользователь может просматривать или редактировать).Я бы не советовал ничего, кроме флагов и полей user_id в самих строках, если вы не очень хорошо разбираетесь в оптимизации запросов.