Вопрос

Я создам приложение с большим количеством похожих элементов (миллионов) и хочу сохранить их в базе данных MySQL, потому что мне нужно вести много статистики и выполнять поиск по конкретным значениям для определенных столбцов.

Но в то же время я буду хранить отношения между всеми элементами, которые связаны во многих связанных структурах, подобных двоичному дереву (транзитивное замыкание), а базы данных отношений не очень хороши для таких структур, поэтому я хотел бы хранить все отношения в Neo4j, которые имеют хорошую производительность для данных такого типа.

Мой план состоит в том, чтобы иметь все данные, кроме отношений, в базе данных MySQL и все отношения с item_id хранится в базе данных Neo4j.Когда я хочу найти дерево, я сначала ищу в Neo4j все item_id:s в дереве, затем я ищу в базе данных MySQL все указанные элементы в запросе, который будет выглядеть так:

SELECT * FROM items WHERE item_id = 45 OR item_id = 345435 OR item_id = 343 OR item_id = 78 OR item_id = 4522 OR item_id = 676 OR item_id = 443 OR item_id = 4255 OR item_id = 4345

Это хорошая идея или я сильно ошибаюсь? Раньше я не использовал графовые базы данных.Есть ли лучшие подходы к моей проблеме?Как в этом случае будет выполняться MySQL-запрос?

Это было полезно?

Решение

Немного мыслей по этому поводу:

Я бы попробовал смоделировать вашу модель предметной области Neo4j, чтобы включить атрибуты каждого узла в граф.Разделив данные на два разных хранилища данных, вы можете ограничить некоторые операции, которые вы, возможно, захотите выполнить.

Я думаю, все сводится к тому, что вы будете делать со своим графиком.Если, например, вы хотите найти все узлы, подключенные к определенному узлу, атрибуты которого (т. е. имя, возраст...что угодно) являются определенными значениями, нужно ли вам сначала найти правильный идентификатор узла в вашей базе данных MySQL, а затем перейти в Neo4j?Это кажется медленным и слишком сложным, хотя все это можно сделать в Neo4j.Итак, вопрос:понадобятся ли вам атрибуты узла при обходе графа?

Изменятся ли ваши данные или они статичны?Наличие двух отдельных хранилищ данных усложнит ситуацию.

Хотя создание статистики с использованием базы данных MySQL может быть проще, чем делать все это в Neo4j, код, необходимый для обхода графа и поиска всех узлов, соответствующих определенным критериям, не слишком сложен.Эта статистика должна определять ваше решение.

Я не могу комментировать производительность запроса MySQL для выбора идентификаторов узлов.Я думаю, это зависит от того, сколько узлов вам нужно будет выбрать, и от вашей стратегии индексации.Однако я согласен с аспектом производительности, когда дело доходит до перемещения по графику.

Вот хорошая статья именно об этом: MySQL против.Neo4j о крупномасштабном обходе графа и в данном случае, когда говорят «большой», они имеют в виду только миллион вершин/узлов и четыре миллиона ребер.Так что это был даже не особенно плотный график.

Другие советы

Реляционные базы данных могут обрабатывать графовые структуры.Некоторые из них могут даже справиться с ними достаточно элегантно (настолько элегантно, насколько это возможно в реляционной базе данных!).

Ключом к общей обработке графов в реляционных базах данных является рекурсивное общее табличное выражение (RCTE), который по сути позволяет итеративно (не рекурсивно, несмотря на название) расширять запрос по набору строк, объединяя запрос, который выбирает корневой набор строк, и запрос, который определяет соседей выбранных на данный момент строк.Синтаксис немного неуклюжий, но он общий и мощный.

RCTE поддерживаются в PostgreSQL, Firebird, SQL Server и, очевидно, в DB2.Oracle имеет другую, но эквивалентную конструкцию;я читал, что последние версии поддерживают правильные RCTE.MySQL не поддерживает RCTE.Если вы не привязаны к MySQL, я бы посоветовал вам рассмотреть возможность использования PostgreSQL, которая, по сути, является гораздо лучшей базой данных во всех отношениях.

Однако похоже, что вам не нужно поддерживать общие графы, а только деревья.В этом случае у вас есть более конкретные варианты.

Один из них — классический, но довольно умопомрачительный. вложенные наборы.

Более простой вариант — хранить путь в каждой строке:это строка, которая представляет положение строки в дереве и обладает тем свойством, что путь к узлу является префиксом пути к любому подузлу, что позволяет очень эффективно выполнять различные запросы о происхождении («является ли узел A дочерним узла B?», «Какой наименьший общий предок узла A и узла B?» и т. д.).Например, вы можете построить путь для строки, пройдя по дереву от корня и соединив идентификаторы строк, встречающихся на пути, косой чертой.Его легко построить, но его нужно будет сохранить, если вы переставите дерево.С помощью столбца пути вы можете ограничить запрос данным деревом, просто добавив and path like '23/%', где 23 это идентификатор корня.

Итак, хотя графовая база данных, вероятно, является лучшим способом хранения и запроса графических данных, это не единственный вариант, и я бы посоветовал вам взвесить преимущества ее использования с преимуществами хранения всех ваших данных в одной базе данных.

В этом вопросе я в основном поддерживаю Binary Nerd, но хотел бы добавить вариацию.Вы можете хранить живые данные в Neo4j, а затем извлекать данные, необходимые для статистики/отчетности, и помещать их в MySQL.Для поиска я бы использовал Интеграция Neo4j-Lucene если это соответствует вашим потребностям.

Вы можете улучшить запрос, используя IN:

SELECT *
FROM items
WHERE item_id IN (45, 345435, 343, 78, 4522, 676, 443, 4255, 4345)

Также не совсем верно, что реляционные базы данных плохо хранят древовидные структуры.Конечно, в MySQL отсутствуют некоторые функции, которые могли бы упростить работу, но большинство других баз данных хорошо ее поддерживают.Oracle имеет CONNECT BY.Большинство основных СУБД имеют ту или иную форму рекурсивных запросов, MySQL является заметным исключением.Возможно, вы могли бы взглянуть на PostgreSQL и посмотреть, соответствует ли он вашим потребностям?

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top