Дело в чем. В комментариях указаны два противоположных взгляда на проблему,
я больше склоняюсь к тому что стандартными реляционными средствами всё это решается просто, если ты посмотрел первую ссылку, то там прям предлагается вариант описания файловой системы с помощью двух таблиц - связей и вершин.
Нам нужно тогда расписать - а какие собственно запросы у нас могут возникнуть, насколько они будут вложенные - и от этого уже отталкиваться и по возможности применить патч.
Оракл например не стесняется строить свой Ldap сервер (IDS) на основе DB-сервера и не думаю, что там особые какие фичи используются.
Вот какой недостаток я нашёл в постгре - мутная система репликации. Репликация нам нужна а)для взаимодействия модулей в рамках виртуальных серверов, б) для репликации собственно "доменной" информации.
Пункт а) мы можем исключить, если проектируем модули полностью автономными друг от друга, нужно просто продумать систему ключей, чтобы они были уникальными в пределах всего сервера.
В сообщении от Friday 15 February 2008 09:54:18 Evgeny Sinelnikov написал(а):
> Приветствую,
[skip]
> Насчёт общих ключей идея интересная. Но можно подуматьне только об
> уникальности ключей, но и о ссылочной целостности при перекрёстных ссылка в
> разных база установленных на одной СУБД.
>
> По поводу структуры хочу привести ещё ряд ссылок, которые мы сегодня (уже
> вчера) обсуждали относительно структуры БД:
>
> - Дерево каталогов NESTED SETS (вложенные множества) и управление
> им<http://www.getinfo.ru/article610.html>
> - Nested Sets в PostgreSQL <http://dull.ru/2005/04/20/nested-sets/>
> - Деревья в базах данных <http://phpwiki.ru/Tree/Ns>
> - Implementing An N-Level Nested
> Tree<http://www.phpriot.com/articles/nested-trees-1>
> - Написание расширений для PostgreSQL с использованием
> GiST<http://www.altlinux.ru/events/writing_postgresql_extensions.html>
Ещё одна ссылка, раз уж на то пошло, из самых сокровенных запасов: самое
понятное описание Nested Sets :
http://dev.mysql.com/tech-resources/articles/hierarchical-data.html
> К этой теории хотелось бы добавить, что на практике объекты всё равно
> ханяться отдельно и лишь указывают на свою принадлежность тому или иному
> контейнеру, поэтому реализовать решение можно поэтапно. Доступ к объектам
> по имени не зависит от его нахождения в дереве, от этого зависят только
> эффективные права на этот объект. Предлагается первоначально реализовать
> плоский набор объектов, а потом добавить иерархию, усложняющую авторизацию
> стеканием прав и тому подобным.
Да, решение о способе хранения иерархической информации далеко от зрелости и
требует дополнительного тестирования. Nested Sets, Adjacency Lists и 28
способов работы с ними, или даже Path Enumeration - всё такое вкусное, но
имеет и свои недостатки.
Поэтому действительно, информацию о структуре дерева лучше вынести в
отдельную(ые) таблицу(ы), которые добавить потом.
Предлагаю выделить следующие этапы (итерации) развития системы авторизации:
1. Плоская структура, подобная /etc/passwd и /etc/groups, но с учетом будущего
и разделением, например, user, computer и service.
Один из вопросов здесь - главная группа пользователя posix. Предлагаю создать
3 группы для этой цели - users, computers и services.
2. ACL. Прямо поверх 1. Отсутствие иерарихий и прочего упростит реализацию.
3. Контейнеры. Следующие 2 подпункта имхо можно реализовывать достаточно
независимо, порядок неважен.
3а. Стекание прав.
3б. Наследование привилегий
4. Включение агентов (btw, именно это слово теперь предлагается использовать
для обозначения субъектов авторизации - user, computer и service -
возражения?) в контейнеры как в группу (ввод, включение по ссылке).
5. Группа в группе, но не в контейнере
6. Тоже самое, но уже и для контейнеров.
> Единственное, на что стоит заложиться - это на связь между группами и
> контейнерами - и те, и другие у нас планировались иметь уникальный gid из
> общего множества. От этого ещё не поздно отказаться в пользу возможности
> включения контейера в группу, что будет означать, стекание группы на все
> объекты контейнера. То есть gid появляется не у всех контейнеров, а только
> у тех, которые добавлены в соотвествующую группу. Правда вот с транзитивным
> замыканием по отношению группа-объект_ в_группе, то тут во всех случаях
> какой-то бардак получается...
Непонятно, зачем. Если группа может включаться в группу, что мешает
распространить то же отношение и на контейнер?
> В общем, для начала можем говорить о правах на объекты и на некий корень, в
> который они свалены. А потом усложнять процедуру вычисления этих прав
> добавлением иерархии объектов.
См. выше.
>
> Ещё один важный момент, который мы вчера (хм... или позавчера) разрешили -
> это права на группы. Дело в том, что новая модульная архитектура
> предполагает, что каждая служба сама хранит свои данные, и то, что это
> может быть дополнительная база в PostgreSQL - это только частный случай.
> Первоначально я предложи такой вариант (как было сказано "не В дереве а НА
> дереве (метафорично)"):
>
> 1) Отвественность за авторизацию несёт только сам сервис, но механизм у них
> всё равно стараемся сохранять единый.
> 2) Общий механизм вычисления прав по дереву или без него реализован в виде
> библиотеки.
> 3) Отдельные сервисы (конфигураторы) хранят права на свои объекты отдельно,
> но могут для них указывать идентификатор контейнера, использующегося при
> вычислении прав с помощью библиотеки.
> 4) При нарушении ссылочной целостности, когда в базе удаляется контейнер,
> на который сущtствуют ссылки извне, вычисление прав определяется политикой
> сервиса - либо права вычисляются без учёта прав внешнего контейнера, либо
> из предположения, что объект с подвешенной ссылкой, хранится в спец.
> контейнере, например корневом, либо доступ к нему запрещается, до момента
> исправления ссылочной целостности.
> 5) Объекты с нарушенной ссылочной целостностью стоит уметь искать, но для
> начала это не важно...
Возможно, нужно дать конфигуратору несколько вариантов хранения информации:
- с расширением схемы - добавлением таблиц;
- с добавлением отдельной БД и выносом ветки туда (вообще интересная идея -
выносить ветки в отдельные БД... хотя для наших целей это вряд ли
пригодится);
- с построением альтернативного дерева в другой БД, используя ту же систему
(код и представление) что и основное дерево, возможно с ссылками на субъектов
из основного дерева;
- с разработкой собственной системы авторизации (для специфичных задач); здесь
необходимо предусмотреть возможность взаимодействия с нашей системой -
дополнения или пересечения прав, стекание по основному дереву...
> Кроме того в дереве так или иначе должен появляться специальный объект (в
> нашей терминологии даже субъект) - сервис или служба. Эта сущность должна
> получать SPN и вероятно uid, чтобы не придумывать дурацких механизмов по
> созданию спец. пользователей и маппингу на них не свойственных для
> пользователей принципалов kerberos - Service Principal Names. Любая служба
> получая идентификатор и SPN, сохраняется в виде объекта в дереве, и имеет,
> как и любой другой объект, свои ACL. Первоначально - это опять-таки таблица
> в плоском пространстве без иерархии.
Поясню, что эти ACL могут использоваться для управления доступом К конкретному
сервису (конфигуратору), то есть кто чем там может рулить (конфигурировать).
Мне это кажется основным механизмом управления правами для конфигураторов, не
требующих сложных наворотов.
Единственное в чем я не уверен, так это в оптимизации запроса поиска
ноды по полному пути - самая частая операция будет.
Прекомпиленые запросы для обхода дерева пользовать низя.
Соответственно нужно, чтобы система умела ловко спускаться по дереву
не возвращаясь наверх после получения очередной ноды, только в этом
случае сложность поиска по пути будет логарифмической.
Ну, это я ещё про постгрю почитаю, но если кто знает - пишите тута!
Если это невозможно, есть разнообразные методы, правда они снижают
нормализацию данных в базе, а значит триггеры на вставках и апдейтах и
обширные локи на этих же операциях - увы.
Связанный вопрос - насколько в постгре надежен механизм транзакций?
Есть у кого опыт, или чужие данные?
Единственное "но" - если мы хотим потенциальную возможность дробить
базу на несколько компов, то - опаньки!
Никаких nested sets, иначе поимеем nested sex с синхронизацией
распределенных поддеревьев.
В этом варианте только ID предка годится, ибо не требует обратного
крестного хода по дереву на каждый апдейт.
Nested Sets приятны и даже главная их проблема - подъем вверх с
update'ами на каждой ноде при вставке и удалении - она не выглядит так
уж страшно в нашем случае, ибо изменения дерева будут случаться редко
в сравнении с чтением.
Единственное в чем я не уверен, так это в оптимизации запроса поиска
ноды по полному пути - самая частая операция будет.
Единственное "но" - если мы хотим потенциальную возможность дробить
базу на несколько компов, то - опаньки!
Никаких nested sets, иначе поимеем nested sex с синхронизацией
распределенных поддеревьев.
В этом варианте только ID предка годится, ибо не требует обратного
крестного хода по дереву на каждый апдейт.
Netsted Sets, по крайней мере в обычном их виде, не подходят для реализации
отношения группа-объект_в_группе - оно же не дерево, а граф.
Что же касается получения пути - пожалуй вполне можно организовать индекс или
вьюшку или вложенный запрос из пар (объект, предок) где предок - не
обязательно прямой, и оттуда уже формировать список предков. Если добавить в
схему level (длина пути по дереву до корня) - то вот тебе и путь, и очень
неплохо считаются стекающие ACL - как max(level) для определенного джойна.
В общем, стоит пощупать несколько вариантов и полюбоваццо на самое красивое
что получится. Но этот мост мы сожжем когда доберемся до него (c).
А оно так и будет - в директорию пишуть редко, а "редко" здесь понятие
сравнительное, сравниваем с чтениями.
Важный момент: я говорю про запись в таблицы с иерархиями, даже не в
таблицы с объектами. Изменение списка и иерархии объектов (а не
свойств объектов) - это действительно редкая операция.
Самая же частая операция - поиск объекта в иерархии (т.е. не по ID, а
по пути). Вот её и стоит заоптимизировать по самые помидоры.
На мой взгляд, единственная задача для БД директории, требующая писать
столько же сколько читать, это аудит.
Соответственно, если предусмотреть разделение объектов аудита и данных
аудита на уровне таблиц, то проблема эта даже не возникнет и можно
вести иерархические деревья в виде nested sets, да и вообще в любом
удобном виде.
Если я правильно помню, то этот граф не свободный, он с ограничениями
на отношения и стекание.
В общем, ентот граф разворачивается в два дерева (блин, или три??)
связанных как раз через узлы и вершины - записи в таблицах объектов.
А с двумя деревами в отдельных таблицах работать веселее чем с полным
графом в одной табличище ;)
> Что же касается получения пути - пожалуй вполне можно организовать индекс или
> вьюшку или вложенный запрос из пар (объект, предок) где предок - не
> обязательно прямой, и оттуда уже формировать список предков.
Согласен полностью - это всё вполне оптимизируется. Главное решить как.
> В общем, стоит пощупать несколько вариантов и полюбоваццо на самое красивое
> что получится. Но этот мост мы сожжем когда доберемся до него (c).
Ну, это как всегда - вопрос сроков. Если сроки терпят, можно
эксперименты себе позволить :)
Ну, это как всегда - вопрос сроков. Если сроки терпят, можноСроки не терпят.
эксперименты себе позволить :)