При работе с иерархическими наборами данных я считаю, что лучше всего подходить к этому с учетом кеширования.Одним из основных преимуществ такого способа решения этой проблемы является то, что он не требует денормализации базы данных в нечто, что может быть сложнее мутировать.
Так как памяти переполняет память (memcache, redis,и т. д.). Для простых разрешений id -> data
поиск выполняется намного быстрее, чем SQL, я бы использовал его для кэширования списка идентификаторов прямых дочерних элементов для каждого узла.Таким образом, вы можете получить приличную производительность с помощью рекурсивного алгоритма для построения полного списка для любого узла.
Чтобы добавить / удалить новый узел, вам нужно будет только аннулировать его 'прямой родительский кеш O(1)
.
Если этого недостаточно, вы можете добавить еще один слой кеша в список всех дочерних узлов каждого узла.Чтобы это работало с прилично изменяемым набором данных, вы должны записать производительность кеша (соотношение свежих / кэшированных обращений) каждого узла и установить уровень допуска для того, когда хранить кеш.Это также может быть сохранено в куче памяти, так как это не жизненно важные данные.
Если вы используете эту более продвинутую модель кэширования, вы должны будете заметить, что эти полные списки дочерних узлов необходимо будет аннулировать, когда любой из нихдети изменены O(log n)
.
Получив список идентификаторов детей, вы можете использовать синтаксис SQL WHERE id IN( id1, id2, .... )
для запроса того, что вы хотите.