Стоит ли использовать 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-запрос?


person Jonas    schedule 29.03.2010    source источник
comment
Можно заменить другое ИЛИ предложением IN :)   -  person Mik378    schedule 13.11.2013
comment
@ Джонас Что ты в итоге сделал. Мне интересно узнать, как вы решили проблему?   -  person user    schedule 15.05.2014
comment
Для новых читателей этого вопроса: в книге Continuous Enterprise Development in Java и в этом коде используется это архитектурное решение. Есть глава, оправдывающая выбор смешивания двух баз данных.   -  person Mats    schedule 16.09.2015


Ответы (4)


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

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

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

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

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

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

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

person Binary Nerd    schedule 29.03.2010
comment
Опасность включения большего количества атрибутов заключается в том, что вы в конечном итоге запихнете все свои данные в базу данных графа. Я думаю, что возможность легко комбинировать несколько типов хранилищ данных, а также легко создавать отчеты об этом необходима. - person Eelco; 09.06.2011
comment
Почему это кажется медленным? Если я получаю идентификатор из запроса neo4j, а затем делаю WHERE IN (ids) в реляционном, почему он должен быть медленным? Гораздо быстрее, чем обходить множество таблиц, создавая соединения, не так ли? Спасибо! - person Luccas; 06.04.2013
comment
@Luccas, это просто кажется медленным и чрезмерно сложным, потому что для большинства этих запросов вы можете выполнять их непосредственно в neo4j и вам не нужно выполнять 2 запроса в разных БД, хотя SQL-запрос по (первичному) индексному идентификатору, очевидно, будет быстрым . - person vish4071; 31.07.2017

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

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

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

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

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

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

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

person Tom Anderson    schedule 08.08.2012

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

person nawroth    schedule 30.03.2010

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

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

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

person Mark Byers    schedule 29.03.2010
comment
Или используйте вложенные наборы, которые хороши для выполнения операций чтения на путях/поддеревьях. Тем не менее, какой бы подход вы ни использовали, для меня это все равно очень похоже на борьбу с инструментом, тогда как работа с базами данных графов для соответствующих данных кажется естественной и имеет дополнительное преимущество (по крайней мере, теоретическое) конкретной оптимизации и визуализации и т. д. - person Eelco; 09.06.2011