Что такое графовая база данных и когда нужен Neo4j
Основы3 минРедакция Innovialabs
Коротко
Графовая база хранит данные как узлы и связи между ними и быстро проходит по цепочкам связей любой глубины; она нужна, когда главный вопрос — «кто с кем и через кого связан», а не «сколько и сколько стоит».
Коротко: что такое графовая база
Графовая база данных хранит данные не в таблицах, а в виде графа:
- узлы (nodes) — сущности: пользователь, товар, компания, карта;
- связи (edges, relationships) — направленные отношения между узлами: «дружит с», «купил», «подчиняется», «использовал»;
- свойства (properties) — пары ключ-значение и у узлов, и у связей: имя, дата, сумма.
Узлы помечаются метками (:User, :Product), связи имеют тип (:BOUGHT). Самая известная графовая СУБД — Neo4j, её язык запросов называется Cypher.
Главное отличие: связь — это не вычисляемый JOIN, а сохранённый объект. Из узла можно сразу перейти к соседям, не ища совпадения ключей по всей таблице.
Почему цепочки связей тяжелы для SQL
В реляционной базе связь — это внешний ключ, и каждый шаг по графу — ещё один JOIN. Пока шагов один-два, всё хорошо. Проблемы начинаются, когда:
- глубина неизвестна заранее — «найти всех, кто связан с этим аккаунтом через любое число переводов»;
- шагов много — «друзья друзей друзей»;
- связи разнотипные — пользователь, устройство, телефон, карта и адрес в одной цепочке.
В SQL такие запросы пишут через рекурсивные CTE (WITH RECURSIVE). Они работают, но их сложно читать, легко получить взрывной рост промежуточных строк, а оптимизатор плохо предсказывает их стоимость. В графовой базе обход по связям — основная операция, и запрос описывается как шаблон пути.
Где графы естественны
| Задача | Вопрос к данным |
|---|---|
| Рекомендации | Что купили люди, которые купили то же, что и вы? |
| Антифрод | Какие аккаунты делят устройство, телефон или карту и образуют кольцо? |
| Оргструктура | Кто все подчинённые руководителя на любом уровне? |
| Маршруты и логистика | Какой кратчайший путь между складами с учётом связей? |
| Права доступа | Есть ли у пользователя доступ к ресурсу через группы и роли? |
| Графы знаний | Как связаны понятия, документы и авторы? |
Пример на Cypher
Рекомендации «друзья друзей, с которыми вы ещё не знакомы»:
MATCH (me:User {id: 42})-[:FRIEND]->(friend)-[:FRIEND]->(candidate)
WHERE candidate <> me
AND NOT EXISTS { (me)-[:FRIEND]->(candidate) }
RETURN candidate.name, count(friend) AS mutual
ORDER BY mutual DESC
LIMIT 10
Запрос читается почти как рисунок: от меня через друга к кандидату. А вот поиск связанных аккаунтов на глубину до четырёх шагов через любые общие объекты:
MATCH (a:Account {id: 'A-1'})-[*1..4]-(linked:Account)
RETURN DISTINCT linked.id
В SQL то же самое потребует рекурсивного запроса с ручной защитой от циклов.
Когда PostgreSQL всё равно лучше
Графовая база — специализированный инструмент. Оставайтесь на PostgreSQL, если:
- основные данные табличные: заказы, платежи, остатки, счета;
- нужны агрегаты и отчёты: суммы, группировки, выгрузки для бухгалтерии;
- связи неглубокие и известны заранее — один-два JOIN с индексами работают быстро;
- иерархия небольшая — оргструктура на сотни сотрудников спокойно обходится через
WITH RECURSIVE; - в команде нет опыта с графовыми базами, а вторую СУБД придётся поддерживать, бэкапить и синхронизировать.
Частый рабочий вариант — гибрид: PostgreSQL остаётся основной базой, а графовая база получает копию нужных связей для рекомендаций или антифрода.
Как принять решение
- Сформулируйте 3–5 главных запросов продукта.
- Если большинство из них про суммы, фильтры и списки — нужна реляционная база.
- Если ключевые запросы — про пути, соседей и цепочки переменной длины — стоит прототипировать на графе.
- Проверьте на реалистичном объёме данных, прежде чем переносить продакшен.
Частые ошибки
- Переносить в граф всю систему, включая платежи и отчётность.
- Моделировать всё как свойства узлов и забывать про связи — тогда граф превращается в медленную таблицу.
- Писать обходы без ограничения глубины (
[*]) на больших графах. - Не продумать синхронизацию, когда граф — копия данных из основной базы.