Pregunta

Esta es una continuación de:
MySQL - ¿Es posible conseguir todo subtemas en una jerarquía?

Tengo una arbitraria profundidad adyacencia lista modelo tabla (I estoy en el punto que I puede convertirlo en un modelo de conjunto anidado .

Me leer los datos de MySQL sobre el uso de un modelo conjunto anidado, aunque parecía tener cada vez más complejo y muy complejo para hacer las funciones básicas tales como la inserción, actualización y borrado.

Otro blog que muestra cómo utilizar un sistema de disparo con el modelo de lista de adyacencia para mantener una tabla de antepasados ??que se relaciona cada objeto a sus antepasados.


Ahora mismo tiene que ser capaz de devolver una lista de todos los hijos de un nodo dado, cambiar o borrar. Esta estructura jerárquica no se cambia todo el tiempo, una vez creado, pero no será una cantidad masiva de las estructuras jerárquicas.

Los tres métodos que veo son:

  1. Creación de un procedimiento almacenado que hacer una consulta recursiva que devuelve todos los niños.

  2. Convertir a conjuntos anidados Modelo que requeriría para entrar en las complejidades y, posiblemente, crear un procedimiento almacenado para agregar, editar y eliminar en eso.

  3. crear la tabla antepasado descritos anteriormente en el inserto disparadores / eliminar de manejar todos los datos.

Si hay otros métodos que no estoy explorando, por favor hágamelo saber y voy a actualizar esta lista.

¿Fue útil?

Solución

Quassnoi ha hacer algunas pruebas de rendimiento en el modelo de conjuntos anidados y el modelo de lista de adyacencia y documentado los resultados y recomendaciones su blog de Adyacencia lista vs conjuntos anidados: MySQL . El resumen ejecutivo es:

  • conjuntos anidados es más rápida para ir a buscar todos los nodos hijos o todos los nodos padre.
  • conjuntos anidados es una mala idea si con frecuencia tiene que actualizar la tabla.

Esta es la conclusión de su artículo:

  

En MySQL, el modelo de conjuntos anidados debe preferirse si los cambios a la estructura hierarhical son poco frecuentes y es asequible para bloquear la mesa para la duración de una actualización (que puede tomar minutos en una mesa de largo).

     

Esto implica la creación de la tabla utilizando motor de almacenamiento MyISAM, la creación de la caja de delimitación de un tipo de geometría como se describió anteriormente, la indexación con un índice espacial y persistiendo el nivel en la tabla.

     

Si los cambios a la tabla son frecuentes o es inaffordable para bloquear la mesa durante un largo periodo de tiempo que implica una actualización, entonces el modelo de lista de adyacencia se debe utilizar para almacenar los datos jerárquica.

     

Esto requiere la creación de una función para consultar la tabla.

El resto de los espectáculos artículo cómo definir la mesa, poner en práctica las consultas y da mediciones de rendimiento. El uso del índice espacial es una idea inteligente para mejorar el rendimiento del modelo conjunto anidado que podría ser nuevo para usted.


Si también está considerando enfoques sin MySQL entonces puede que desee ver en PostgreSQL que es otra libre y la base de datos de código abierto. PostgreSQL soporta consultas recursivas de la forma de recursiva expresiones de tabla común que hacen que la consulta de datos jerárquica más fácil que en MySQL y también dan un mejor rendimiento. Quassnoi también ha escrito un artículo de Adyacencia lista anidada vs. conjuntos: PostgreSQL que muestra los detalles

.

Si bien estamos hablando de mirar a otros enfoques, la base de datos de Oracle es también una mención merece la pena. Oracle también tiene un CONNECT BY extensión personalizada que hacen que la consulta de datos jerárquica muy fácil y rápido. Quassnoi del artículo de Adyacencia lista vs conjuntos anidados: Oracle cubre de nuevo los datos de rendimiento. La consulta que necesita para obtener todos los niños es extremadamente simple en este caso:

SELECT *
FROM yourtable
START WITH id = 42
CONNECT BY parent = PRIOR id

Otros consejos

Siempre iría con el conjuntos anidados para la simplicidad y conveniencia de cizalla. Siempre sugiero este artículo . Muestra excelente las consultas que se necesitan para el trabajo con dichos datos hierachrchical. La única desventaja que veo aquí es que se puede conseguir más lento con la inserción / updateing nuevos registros cuando el hierachry alcanza un cierto nivel de complejidad, pero la lectura es más rápido que muchas otras soluciones que hae visto.

Sólo para dar un ejemplo del artículo de arriba:

SELECT t1.name AS lev1, t2.name as lev2, t3.name as lev3, t4.name as lev4
FROM category AS t1
LEFT JOIN category AS t2 ON t2.parent = t1.category_id
LEFT JOIN category AS t3 ON t3.parent = t2.category_id
LEFT JOIN category AS t4 ON t4.parent = t3.category_id
WHERE t1.name = 'ELECTRONICS';

+-------------+----------------------+--------------+-------+
| lev1        | lev2                 | lev3         | lev4  |
+-------------+----------------------+--------------+-------+
| ELECTRONICS | TELEVISIONS          | TUBE         | NULL  |
| ELECTRONICS | TELEVISIONS          | LCD          | NULL  |
| ELECTRONICS | TELEVISIONS          | PLASMA       | NULL  |
| ELECTRONICS | PORTABLE ELECTRONICS | MP3 PLAYERS  | FLASH |
| ELECTRONICS | PORTABLE ELECTRONICS | CD PLAYERS   | NULL  |
| ELECTRONICS | PORTABLE ELECTRONICS | 2 WAY RADIOS | NULL  |
+-------------+----------------------+--------------+-------+
6 rows in set (0.00 sec)

SQL sabia, creo que no se puede conseguir más bonito y más simple;)

No tengo idea a la procedimiento almacenado manera. Pero ya que involces recursión (en su caso), no sé si va a ser rápido con muchos niveles de la jerarquía. Asumo que puede darle una oportunidad.

Tal vez usted debería considerar el uso de base de datos documental como MongoDB . Se podría hacer su vida mucho más fácil.

Cuando se trata de conjuntos de datos jerárquicos Me parece que lo mejor es acercarse a ella con el almacenamiento en caché en mente. Uno de los principales beneficios de este modo de tratar con este problema de esta manera es que no requiere que usted de-la normalización de la base de datos en algo que podría ser más difícil de mutar.

Desde (memcache, Redis, etc) las búsquedas de las pilas de memoria son mucho más rápido que SQL para resoluciones simples id -> data, yo utilizo para almacenar en caché una lista de los identificadores de los niños directos para cada nodo. De esta manera se puede obtener un rendimiento decente a través de un algoritmo recursivo para construir una lista completa para cualquier nodo.

Para añadir / eliminar un nodo nuevo, sólo tendrá que invalidar su O(1) caché matriz directa.

Si eso no es lo suficientemente rápido, se puede añadir otra capa de caché a una lista de todo hijo de un nodo en cada nodo. Para que esto funcione con un conjunto de datos con decencia mutable, se debe registrar el rendimiento de la caché (proporción de éxitos frescas / caché) de cada nodo y establecer un nivel de tolerancia para cuando para almacenar la memoria caché. Esto también se puede almacenar en un montón de memoria, ya que es de datos no vital.

Si se utiliza este modelo de almacenamiento en caché más avanzada, tendrá que tener en cuenta que estos niños completos nodo listas tendrán que ser invalidada cuando cualquiera de sus hijos se cambian O(log n).

Una vez que tenga su lista de hijos de identificación de puede utilizar la sintaxis SQL para WHERE id IN( id1, id2, .... ) de consulta por lo que quieres.

Una vez tuvo que guardar un sistema de lista de material complejo jerárquica arbitraria profundidad en un gestor de base de datos SQL-como que no era realmente a la altura, y terminó forzando desordenados y complicados índices del, definiciones de datos, consultas, etc. Después de reiniciar desde cero, utilizando el administrador de db para proporcionar solamente una API para el registro lee y escribe en las claves indexados simples, y haciendo todo de la entrada / manipulación real / presentación de informes en código externo, el resultado final fue más rápido de implementar , más fácil de entender, y más fácil de mantener y mejorar. La consulta más compleja necesitaba era SELECCIONAR esencialmente A de B.

Así que, en lugar de incrustar la lógica y las operaciones dentro de las restricciones de MySQL, considere la posibilidad de golpear a cabo código para hacer lo que quiere, y confiando en MySQL sólo para el nivel más bajo obtiene / puts.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top