que pagina oficial architecture mysql hierarchical-data neo4j graph-databases

architecture - pagina - ¿Es una buena idea usar MySQL y Neo4j juntos?



neo4j pagina oficial (4)

Haré una aplicación con muchos elementos similares (millones) y me gustaría almacenarlos en una base de datos MySQL, porque me gustaría hacer muchas estadísticas y buscar valores específicos para columnas específicas.

Pero al mismo tiempo, almacenaré las relaciones entre todos los elementos, que están relacionados en muchas estructuras de árbol binario conectadas (cierre transitivo), y las bases de datos de relaciones no son buenas en ese tipo de estructuras, por lo que me gustaría almacenar todas las relaciones en Neo4j que tienen un buen rendimiento para este tipo de datos.

Mi plan es tener todos los datos excepto las relaciones en la base de datos MySQL y todas las relaciones con item_id almacenadas en la base de datos de Neo4j. Cuando quiero buscar un árbol, primero busco en el Neo4j todos los item_id : s en el árbol, luego busco en la base de datos MySQL todos los ítems especificados en una consulta que se vería así:

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

¿Es esta una buena idea, o estoy muy equivocado? No he usado las bases de datos de gráficos antes. ¿Hay algún mejor enfoque para mi problema? ¿Cómo funcionaría la consulta MySQL en este caso?


Las bases de datos relacionales pueden manejar estructuras de gráficos. Algunos de ellos incluso pueden manejarlos de forma moderadamente elegante (¡tan elegantemente como lo hace una base de datos relacional!).

La clave para el manejo general de gráficos en bases de datos relacionales es la expresión de tabla común recursiva (RCTE), que básicamente le permite iterativamente (no recursivamente, a pesar del nombre) expandir una consulta sobre un conjunto de filas, combinando una consulta que selecciona un conjunto raíz de filas y una consulta que define los vecinos de las filas seleccionadas hasta el momento. La sintaxis es un poco torpe, pero es general y poderosa.

Los RCTE son compatibles con PostgreSQL, Firebird, SQL Server y aparentemente en DB2. Oracle tiene una construcción diferente pero equivalente; He leído que las versiones recientes son compatibles con los RCTE adecuados. MySQL no es compatible con RCTE. Si no está casado con MySQL, le recomendaría que considere utilizar PostgreSQL, que básicamente es una base de datos mucho mejor.

Sin embargo, parece que no es necesario que admita gráficos generales, solo árboles. En ese caso, hay opciones más específicas abiertas para usted.

Uno de ellos es el clásico, pero en cambio, juegos anidados que cambian la mente.

Una más simple es almacenar una ruta con cada fila: esta es una cadena que representa la posición de la fila en el árbol, y tiene la propiedad de que la ruta para un nodo es un prefijo de la ruta para cualquier subnodo, lo que le permite de manera muy eficiente hacer varias consultas sobre la ascendencia ("¿es el nodo A un hijo del nodo B?", "¿cuál es el nodo A y el ancestro común más bajo del nodo B?", etc.). Por ejemplo, podría construir una ruta para una fila al recorrer el árbol desde la raíz y unir las ID de las filas encontradas en el camino con barras diagonales. Esto es fácil de construir, pero se debe mantener si reorganizas el árbol. Con una columna de ruta, puede restringir una consulta a un árbol dado simplemente agregando una and path like ''23/%'' , donde 23 es la ID de la raíz.

Entonces, aunque una base de datos de gráficos es probablemente la mejor manera de almacenar y consultar datos de gráficos, no es la única opción, y le sugiero que sopese las ventajas de usar uno con las ventajas de tener todos sus datos en una única base de datos.


Pocos pensamientos sobre esto:

Intentaría modelar tu modelo de dominio Neo4j para incluir los atributos de cada nodo en el gráfico. Al separar sus datos en dos almacenes de datos diferentes, puede limitar algunas operaciones que podría querer hacer.

Supongo que todo se reduce a lo que harás con tu gráfico. Si, por ejemplo, desea encontrar todos los nodos conectados a un nodo específico cuyos atributos (es decir, nombre, edad ... lo que sea) son ciertos valores, primero tendría que encontrar el ID de nodo correcto en su base de datos MySQL y luego entrar en Neo4j? Esto parece lento y demasiado complicado cuando puedes hacer todo esto en Neo4j. Entonces la pregunta es: ¿necesitarás los atributos de un nodo al atravesar el gráfico?

¿Cambiarán sus datos o es estático? Tener dos almacenes de datos separados complicará las cosas.

Si bien generar estadísticas usando una base de datos MySQL podría ser más fácil que hacer todo en Neo4j, el código requerido para atravesar un gráfico para encontrar todos los nodos que cumplan con un criterio definido no es demasiado difícil. Lo que estas estadísticas son lo que debe conducir su solución.

No puedo comentar sobre el rendimiento de la consulta MySQL para seleccionar identificadores de nodo. Supongo que eso se reduce a la cantidad de nodos que deberá seleccionar y su estrategia de indexación. Sin embargo, estoy de acuerdo sobre el lado del rendimiento cuando se trata de atravesar un gráfico.

Este es un buen artículo sobre esto: MySQL vs. Neo4j en una gráfica de gran escala y en este caso, cuando dicen grande, solo significan un millón de vértices / nodos y cuatro millones de bordes. Entonces ni siquiera era un gráfico particularmente denso.


Principalmente estoy con Binary Nerd en esto, pero me gustaría agregar una variación. Puede almacenar los datos en vivo en Neo4j y luego extraer los datos que necesita para estadísticas / informes y ponerlos en MySQL. Para las búsquedas iría con la integración Neo4j-Lucene si eso se adapta a sus necesidades.


Puede mejorar la consulta utilizando IN:

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

Tampoco es del todo cierto que las bases de datos relacionales sean malas para almacenar estructuras de árbol. Ciertamente, MySQL no cuenta con alguna funcionalidad que lo haga más fácil, pero la mayoría de las demás bases de datos lo soportan bien. Oracle tiene CONNECT BY . La mayoría de los RDBMS dominantes tienen alguna forma de consultas recursivas, MySQL es una excepción notable. ¿Quizás podría echar un vistazo a PostgreSQL y ver si eso satisface sus necesidades?