Моя ситуация такова, что в настоящее время я храню иерархию в базе данных SQL, которая быстро приближается к 15000 узлам (5000 ребер).Эта иерархия определяет мою модель безопасности на основе позиции пользователя в дереве, предоставляя доступ к элементам ниже.Поэтому, когда пользователь запрашивает список всех защищенных элементов, я использую CTE для его повторения в БД (и выравнивает все элементы), который начинает показывать его возраст (медленно).
Иерархияменяются не часто, поэтому я попытался переместить его в оперативную память (redis).Имея в виду, у меня есть много подсистем, которые нуждаются в этом для вызовов безопасности, и пользовательский интерфейс для построения дерева для операций CRUD.
Первая попытка
Моя первая попытка сохранить отношения в виде пары ключ-значение (это то, как она хранится в базе данных)
E
/ \
F G
/ \ / \
H I J K
mapped to:
E - [F, G]
F - [H, I]
G - [J, K]
Поэтому, когда я хочу E и все его потомки, я рекурсивнополучить его дочерний элемент и его дочерний элемент с помощью ключей, и это позволит мне начать движение с любого узла.Это решение дало хорошее увеличение скорости, но с 15 000 узлов было приблизительно 5000 обращений к кэшу, чтобы перестроить мое дерево в коде (в худшем случае ... начиная с E. производительность зависит от местоположения начальных узлов, в результате чего суперпользователи видятхудшая производительность).Это было все еще довольно быстро, но казалось болтливым.Мне нравится тот факт, что я могу удалить узел в любое время, вынув его из списка ключей, не перестраивая весь кэш.Это также быстро освещалось для визуального построения дерева по требованию в пользовательском интерфейсе.
Вторая попытка
Моя другая идея состоит в том, чтобы взять Иерархию из базы данных, построить дерево и сохранить его в ОЗУ (redis), а затем вытащить всю вещь из памяти (она была размером примерно 2 МБ, сериализована).Это дало мне один вызов (не слишком болтливый) в redis, чтобы вытащить все дерево, найти родительский узел пользователей и спуститься, чтобы получить все дочерние элементы.Эти вызовы частые, и передача 2 МБ на сетевом уровне казалась большой.Это также означает, что я не могу легко добавить / удалить и элемент, не потянув дерево вниз, не отредактировав и не оттолкнув его назад.Кроме того, построение деревьев по требованию через HTTP означало, что каждый запрос должен был сбрасывать 2 МБ, чтобы получить только прямых потомков (очень мало при первом решении).
Итак, какое решение, по вашему мнению, является лучшим подходом (в долгосрочной перспективе, поскольку оно продолжает расти).Оба вызывающе быстрее и снимают нагрузку с базы данных.Или это лучший способ сделать это, о котором я не думал?
Спасибо