Хорошо ли использовать MySQL и Neo4j вместе?
Я создам приложение с большим количеством похожих элементов (миллионы), и я хотел бы их хранить в базе данных 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-запрос в этом случае?
Ответы
Ответ 1
Немногие мысли по этому поводу:
Я бы попробовал моделировать вашу модель домена Neo4j, чтобы включить атрибуты каждого node в график. Разделив данные на два разных хранилища данных, вы можете ограничить некоторые операции, которые вы, возможно, захотите сделать.
Я предполагаю, что дело доходит до того, что вы будете делать с вашим графиком? Если, например, вы хотите найти все узлы, подключенные к определенному node, чьи атрибуты (то есть имя, возраст.. что угодно) являются определенными значениями, вам сначала нужно найти правильный node ID в базе данных MySQL, а затем зайдите в Neo4j. Это просто кажется медленным и чрезмерно сложным, когда вы можете сделать все это в Neo4j. Итак, вопрос в том, нужны ли вам атрибуты node при прохождении графика?
Будут ли ваши данные изменяться или статичны? Имея два отдельных хранилища данных, это усложнит ситуацию.
В то время как генерация статистики с использованием базы данных MySQL может быть проще, чем выполнение всего в Neo4j, код, необходимый для прохождения графика, чтобы найти все узлы, которые соответствуют определенным критериям, не слишком сложно. Что эти статистические данные должны управлять вашим решением.
Я не могу прокомментировать производительность MySQL-запроса, чтобы выбрать node ids. Я думаю, это сводится к тому, сколько узлов вам нужно будет выбрать и ваша стратегия индексирования. Я соглашаюсь с тем, что касается производительности, когда дело доходит до прохождения графика.
Это хорошая статья только для этого: MySQL против Neo4j на широкомасштабном графическом обходе, и в этом случае, когда они говорят большие, они означают только миллионы вершин/узлов и четыре миллиона ребер. Таким образом, это был даже не особенно плотный граф.
Ответ 2
Реляционные базы данных могут обрабатывать структуры графов. Некоторые из них могут даже обрабатывать их умеренно элегантно (так же элегантно, как и реляционная база данных!).
Ключом к общей обработке графа в реляционных базах данных является рекурсивное общее табличное выражение (RCTE), которое в основном позволяет вам итеративно (не рекурсивно, несмотря на имя), разверните запрос по набору строк, объединив запрос, который выбирает корневой набор строк и запрос, который определяет соседние строки, выбранные до сих пор. Синтаксис немного неуклюжий, но он общий и мощный.
RCTE поддерживаются в PostgreSQL, Firebird, SQL Server и, по-видимому, в DB2. У Oracle есть другая, но эквивалентная конструкция; Я читал, что последние версии поддерживают правильные RCTE. MySQL не поддерживает RCTE. Если вы не привязаны к MySQL, я бы настоятельно рекомендовал вам использовать PostgreSQL, который в основном представляет собой гораздо лучшую базу данных.
Однако, похоже, вам не нужно поддерживать общие графики, просто деревья. В этом случае вам доступны более конкретные варианты.
Один из них - классический, но скорее мыслящий вложенный набор.
Простейшим является сохранение пути с каждой строкой: это строка, которая представляет позицию строки в дереве и имеет свойство, что путь для node является префиксом пути для любого поднода, который позволяет очень эффективно выполнять различные запросы о происхождении ( "is node A a child of node B?", "что такое node A и node B самый низкий общий предок?" и т.д.). Например, вы можете построить путь для строки, пройдя дерево из корня и присоединяя идентификаторы строк, встречающихся на пути с помощью косой черты. Это просто построить, но заботится о том, чтобы сохранить, если вы измените дерево. С помощью столбца пути вы можете ограничить запрос данным деревом просто добавив and path like '23/%'
, где 23
- это идентификатор корня.
Итак, хотя база данных графа, вероятно, является лучшим способом хранения и запроса данных графа, это не единственный вариант, и я бы предложил вам взвесить преимущества использования одного из преимуществ наличия всех ваших данных в одном базы данных.
Ответ 3
В основном я использую Binary Nerd, но хочу добавить вариант. Вы можете сохранить текущие данные в Neo4j, а затем извлечь данные, необходимые для статистики/отчетности, и поместить в MySQL. Для поиска я бы пошел с интеграцией Neo4j-Lucene, если это соответствует вашим потребностям.
Ответ 4
Вы можете улучшить запрос, используя IN:
SELECT *
FROM items
WHERE item_id IN (45, 345435, 343, 78, 4522, 676, 443, 4255, 4345)
Также не совсем верно, что реляционные базы данных плохо хранят древовидные структуры. Разумеется, в MySQL отсутствует некоторая функциональность, которая упростит ее работу, но большинство других баз данных хорошо ее поддерживают. Oracle имеет CONNECT BY
. Большинство основных RDBMS имеют некоторую форму рекурсивных запросов - MySQL является заметным исключением. Возможно, вы можете взглянуть на PostgreSQL и посмотреть, соответствует ли это вашим потребностям?