Задачи, рождённые для графа

Подборка реальных задач, где связи — главное, и почему именно в них граф раскрывается.

Connected data (связанные данные) — предметная область, ценность которой в значительной мере определяется отношениями между сущностями, а не самими сущностями.

Признак «графовой» задачи

Прежде чем тащить новую базу в проект, полезно научиться распознавать задачи, для которых граф создан. Признак простой: если вы постоянно спрашиваете «как связаны эти сущности», «есть ли путь между ними», «кто посередине», «что похоже через общих соседей» — это графовая задача. Если же вопросы звучат как «дай агрегат по колонке за месяц» — это аналитика, и для неё есть свои инструменты.

Удобно держать в голове короткий чек-лист. Задача тяготеет к графу, когда одновременно верны несколько пунктов: связей между сущностями много и они разнотипные; обходы идут вглубь (не один-два шага, а пять-десять); структура связей нерегулярна (нельзя заранее сказать, сколько у узла соседей); и сам вопрос формулируется через путь, цепочку или окрестность, а не через таблицу значений. Чем больше пунктов совпало, тем увереннее можно брать граф.

Антипризнаки

Симметрично полезно знать, когда граф не нужен, даже если связи в данных есть. Если связь ровно одна и фиксированной кратности («у заказа один клиент»), это прекрасно ложится на внешний ключ и никакого графа не требует. Если главный вопрос — это агрегат («средний чек», «выручка по месяцам»), вы упрётесь в сильную сторону колоночных и реляционных СУБД, а не графа. И если данные по сути табличные и плоские, граф добавит концептуальной сложности, ничего не ускорив. Хорошее правило: тянуться за графом стоит тогда, когда именно обход связей стал узким местом или главным вопросом.

Пять классических областей

1. Рекомендательные системы

«Покупатели, купившие это, также купили то». В графе это поиск узлов, до которых можно дойти через общих соседей: от товара — к покупателям — к их другим товарам. Сила сигнала измеряется числом общих путей.

(Вы)-[:КУПИЛ]->(Книга A)<-[:КУПИЛ]-(Другие)-[:КУПИЛ]->(Книга B)

Чем больше «других», прошедших путь к Книге B, тем увереннее рекомендация. Сила графового подхода здесь в том, что один и тот же движок обхода легко обобщается: можно учитывать не только совместные покупки, но и просмотры, лайки, жанры, авторов — просто добавляя новые типы связей и удлиняя паттерн. В реляционной модели каждый такой новый сигнал означал бы ещё одну таблицу-связку и ещё один JOIN в и без того тяжёлом запросе.

2. Антифрод (fraud detection)

Мошеннические схемы — это кольца и кластеры: одни и те же телефоны, адреса, карты, устройства, переиспользуемые разными «независимыми» аккаунтами. В таблицах такое кольцо невидимо, в графе оно буквально рисуется как плотный подграф, который ищется обходом. Классический сигнал — когда несколько якобы разных пользователей сходятся в одной точке:

(Аккаунт A)─┐
(Аккаунт B)─┼─>(Устройство 0xAB)
(Аккаунт C)─┘

Три «независимых» аккаунта, делящих одно устройство и одну карту, — это подозрительная звезда, которую обход находит за миллисекунды. А поскольку мошенники маскируются, переставляя посредников, важна именно способность искать схему любой формы и глубины, а не конкретный заранее известный шаблон.

3. Граф знаний (knowledge graph)

Понятия и факты как сеть: «Москва — столица — Россия», «Россия — граничит — Казахстан». На таких графах строятся поисковые подсказки, голосовые ассистенты, корпоративные базы знаний. Ценность в том, что факты складываются в цепочки: из «Москва — столица — Россия» и «Россия — на континенте — Евразия» система выводит, что Москва находится в Евразии, не храня этот факт явно. Именно так поисковики отвечают на вопросы вроде «в какой стране снимали этот фильм» — собирая ответ обходом нескольких рёбер графа.

4. Маршруты и сети

Дороги, логистика, авиаперелёты, телеком-сети, зависимости пакетов. Кратчайший путь, узкие места, что отвалится при сбое узла — всё это естественные графовые запросы. Здесь часто важны веса на рёбрах: километры, минуты, цена, пропускная способность. Алгоритмы вроде поиска кратчайшего пути работают прямо на структуре графа, и графовая база даёт их почти даром, тогда как в реляционной модели такие алгоритмы приходится эмулировать рекурсивными запросами или вытаскивать данные в приложение.

5. IT-инфраструктура и зависимости

Сервис зависит от базы, база — от диска, диск — от стойки. Вопрос «что сломается, если упадёт стойка №7» — это обход графа зависимостей вниз. CMDB и impact-анализ — классическое применение. Обратный обход (вверх по зависимостям) отвечает на не менее важный вопрос «от чего зависит этот сервис, что нужно поднять раньше него». Одна и та же модель, пройденная в двух направлениях, закрывает и анализ последствий сбоя, и планирование порядка развёртывания.

Как работает под капотом

Во всех этих задачах общий вычислительный паттерн — обход (traversal): мы стартуем из узла и шагаем по рёбрам, накапливая результат. Граф ускоряет именно обход. Поэтому правило большого пальца такое: чем глубже и нерегулярнее обход, тем сильнее преимущество графа над JOIN-ами. Запрос на 1–2 уровня связей реляционная база ещё вытянет; на 4–6 уровнях с ветвлением граф уходит в отрыв на порядки.

Стоит различать два режима работы с графом. Первый — транзакционные обходы: короткие локальные запросы вроде «рекомендации для этого пользователя прямо сейчас», которые исполняются на лету и должны укладываться в миллисекунды. Второй — графовая аналитика: тяжёлые алгоритмы на всём графе (поиск сообществ, расчёт важности узлов вроде PageRank, выявление кластеров), которые гоняют пакетно. Neo4j закрывает оба режима: Cypher — для первого, отдельная библиотека графовых алгоритмов — для второго. Понимание, в каком режиме живёт ваша задача, помогает выбирать правильный инструмент внутри экосистемы.

Частые ошибки

  • Тащить в граф аналитику. «Сумма продаж по регионам за квартал» — это колоночная/реляционная задача, граф тут не нужен.
  • Моделировать граф ради моды. Если связи мелкие и обходов нет, граф добавит сложности без выгоды.
  • Недооценивать гибридность. Часто лучший ответ — граф для связей плюс привычная СУБД/поиск для остального, а не «всё в одну базу».

Итоги

  • Графовые задачи распознаются по вопросам про связи, пути и похожесть через соседей.
  • Классика: рекомендации, антифрод, графы знаний, маршруты, зависимости инфраструктуры.
  • Общий движок всех этих задач — обход графа; чем он глубже, тем больше выигрыш.
  • Аналитика-агрегаты — не для графа; здесь честнее реляционная или колоночная база.
Проверьте себя
1. Какой вопрос НЕ является типично графовой задачей?
AЕсть ли путь между двумя людьми?
BКто покупал товары вместе с этим?
CКакова сумма продаж по регионам за квартал?
DКакие аккаунты делят одно устройство?
2. Почему антифрод хорошо ложится на граф?
AМошенники используют SQL
BСхемы образуют плотные кластеры из общих телефонов/карт/устройств, которые видны как подграф
CГраф шифрует данные
DВ графе нельзя подделать запись
3. Когда преимущество графа над JOIN-ами максимально?
AНа запросах в 1 уровень связи
BПри простой сортировке
CПри глубоких обходах в 4–6 уровней с ветвлением
DПри вставке одной строки