Допустим, есть система, и у вас есть три объекта:
- Пользователь
- Команда (группа пользователей)
- Роль
И вы хотите настроить некоторые отношения разрешений с гибкостью в базе данных в любом случае, например:
- Пользователь X может изменять права доступа пользователя Y
- Пользователь X может изменять разрешения Команды Y
- Пользователь X может изменять разрешения для роли Y
- Команда X может изменять разрешения роли Y
- Команда X может изменять разрешения Команды Y
- Роль X может изменять разрешения команды Y
- Роль X может изменять права на роль Y
В аналогичном сценарии у меня в настоящее время есть таблица со следующей схемой:
- SubjectType (Пользователь | Команда | Роль)
- SubjectId (целое число - не внешний ключ)
- TargetType (Пользователь | Команда | Роль)
- TargetId (целое число - не внешний ключ)
Это позволяет указывать все отношения в одном месте, однако, поскольку нет указанных отношений, возникает проблема:
- Роль A настроена для доступа к командам с идентификаторами команд X, Y, Z
- Команды Y и Z удалены без ошибок в других местах
- При запросе целей для роли A идентификаторы команд Y и Z по-прежнему возвращаются.
В нынешнем виде я вижу два варианта, каждый со своим компромиссом (плюсы = +, минусы = -):
1. Оставьте как есть с данными в одном месте, но удалите потерянные отношения разрешения при удалении объекта.
- (+) Сохраняет простоту одной таблицы и одного запроса.
и вручную удалить записи о разрешениях команды при удалении команды
- (-) Потребуется 3 операции удаления вручную (Пользователь | Команда | Роль). Хотя будет одна функция удаления, в которой это может происходить повторяющимся образом, нет жесткого и быстрого поручительства
2. Укажите каждое отношение в своей таблице.
- (+) Гарантия ACID предотвратит потерю записей
- (-) Гораздо большая многословность таблиц, 7-9 таблиц для одного и того же
- (-) Больше запросов, больше объединений (особенно если используется наследование таблиц классов)
Я склоняюсь ко второму варианту с мыслью добавить дополнительную сложность ниже и абстрагировать ее в функции единого доступа, и думаю, что это стоит дополнительной работы (требует немного переписать).
Однако мне интересно, есть ли другой вариант, который я пропустил, или есть какие-то сильные, основанные на опыте рекомендации по этой проблеме?
Использование SQL Server 2012 с этой настройкой, но я предполагаю, что это общая проблема SQL / базы данных.