Есть альтернативный подход, который мы используем там, где я работаю.
Администрирование системы сложное, поэтому у нас есть понятие ролей или профилей, если хотите. Роль или профиль определяют, какие действия может выполнять пользователь и какие данные.
Тогда у нас есть древовидная структура для пользователей. Пользователь принадлежит офису, который принадлежит отделу, который принадлежит отделу и т.д ...
Для администрирования каждому элементу дерева может быть присвоен любой профиль (и несколько из них при необходимости).
Если бы мы сохранили это как есть, это привело бы к увеличению числа запросов, поскольку простой вопрос, подобный тому, который вы оговариваете may user X modify Y ?
, потребовал бы собрать все профили, собрать все атрибуты ролей для каждого профиля, а затем, наконец, Разработайте роли, чтобы проверить, авторизовано ли действие.
Чтобы упростить запрос, периодически создается денормализованная версия таблиц (скажем, ежечасно), и запросы выполняются к денормализованной версии (хранящейся в базе данных sqlite).
Конечно, это означает, что у вас есть некоторое время, чтобы изменения, сделанные администратором, вступили в силу (вам нужно подождать, пока денормализация + репликация), но это работает довольно хорошо, поскольку у вас есть лучшее из обоих миров:
- администраторы имеют нормализованное представление
- запросы сверхбыстрые
Хитрость в том, чтобы иметь правильный механизм «репликации». Используя базу данных sqlite, вы сначала генерируете файл, а затем копируете его на каждую машину, переводите входящую транзакцию (только для чтения) в режим ожидания и ждете, пока транзакция не выполняется, перемещаете новую базу данных вместо старой, и возобновить ожидающие транзакции. Он работает довольно хорошо, но это означает, что вы не хотите обновлять файл базы данных каждую секунду.