Обзорная статья на тему применения materialized path
для оптимизации запросов по ассоциативным связям. Содержит разбор алгоритма.
Перед прочтением этой статьи рекомендуется ознакомиться с предыдущими статьями: Фактор рефакторинга и Ассоциативные связи.
В Deep.Case для использования системы не требуется понимать описанное в статье. Материал предназначен для читателя, знакомого с SQL и GraphQL.
{
links: links(where: {
_by_item: { path_item_id: { _eq: 56 } },
}) {
id
}
}
{
"data": {
"links": [
{ "id": 56 },
{ "id": 57 },
{ "id": 58 },
{ "id": 59 },
{ "id": 60 },
{ "id": 61 },
{ "id": 62 },
{ "id": 63 },
{ "id": 64 },
{ "id": 65 },
{ "id": 66 },
{ "id": 67 },
{ "id": 68 }
]
}
}
В Deep.Case используется решение оптимизации поиска по деревьям. На уровне пакетов (связей описывающих типы и модели данных, код реакций и правила применения), их авторы могут определять, по каким связям будут проходить деревья индексации. При правильном использовании, это позволяет избежать travers(а) десятками или сотнями join, а получать желаемые результаты за 2-5 join.
Нативный SQL-like доступ к связям удобен для задания точечных критериев поиска, однако этого было бы не достаточно само по себе, так как позволяло бы только делать traverse с помощью join каждый раз переходя от связи к связи. С помощью По определенным типам можно выстраивать множество пересекающихся разнонаправленных деревьев (Trees ) индексации, что позволяет делать запросы по диапозонам деревьев, а не по отдельным связям.
SQL предполагает выделение доменов. Нам кажется, у этого есть две основные причины: выделение таблиц для оптимизации и снижение когнитивной нагрузки разработчика.
При ассоциативном подходе роль домена разбита на:
Ассоциативные модели (на эту тему будут отдельные статьи [если от кармы что-то останется]) создаваемые независимыми авторами. Модели-пакеты обобщают связи (как например типы связей для построения своих данных) в некоторый самостоятельный смысл - как, например, Blog Post или WalletBalance. Можно воспринимать как схему данных/типизацию. Не включает в себя роль оптимизации.
Materialized path group (mp_group
и mp_include
-связи управляют правилами индексации), создаваемые, как авторами распространяемых ассоциативных моделей, так и автором проекта. Индексирует деревья, использующие определенные типы связей. Позволяет получать деревья по критериям глубины, ограничителей, включения определенных связей. Реализует роль оптимизации.
Тип mp_group
, экземпляры которого не могут ссылаться на кого-либо. Тип mp_include
, который может с помощью from_id
ссылаться на какой-то определенный экземпляр mp_group
, и с помощью to_id
ссылаться на тип связей, по которому mp должен проходить.
В начале мы опустим типизацию модели и то, как указывать правила индексации. Предположим, что все связи изначально проиндексированы с помощью нашего materialized path.
Допустим, у нас есть дерево из связей A |- C -> B |- E -> D
. Что мы можем о нем узнать благодаря индексации?
Наша модификация materialized-path позволяет индексировать пересекающиеся деревья c множеством родителей.
Траверс и рекурсия - главные враги. Поддержка рекурсивного mp была бы слишком затратна, так как требовала бы