sql >> Base de Datos >  >> RDS >> Mysql

Lograr jerarquía, relación padre/hijo de una manera fácil y efectiva

Desafortunadamente, si no puede cambiar el modelo de datos y está usando MySQL, está atrapado en una situación en la que necesita consultas recursivas y está usando un DBMS que no admite consultas recursivas.

Quassnoi escribió una serie interesante de artículos de blog, mostrando técnicas para consultar datos jerárquicos. Sus soluciones son bastante inteligentes, pero muy complejas.http:// expliqueextended.com/2009/03/17/hierarchical-queries-in-mysql/

PostgreSQL es otro RDBMS de código abierto, que admite consultas recursivas , por lo que podría obtener un árbol completo almacenado en la forma que muestra. Pero si no puede cambiar el modelo de datos, supongo que no puede cambiar a un RDBMS diferente.

Hay varios modelos de datos alternativos que hacen que sea mucho más fácil obtener árboles arbitrariamente profundos:

  • Mesa de cierre
  • Conjuntos anidados, también conocido como Recorrido de árbol de pedido anticipado modificado
  • Enumeración de ruta, también conocida como ruta materializada

Los cubro en mi presentación Modelos para datos jerárquicos con SQL y PHP , y en mi libro Antipatrones SQL:Cómo evitar las trampas de la programación de bases de datos .

Finalmente, hay otra solución que he visto usar en el código para Slashdot , por sus jerarquías de comentarios:almacenan "parent_id" como en la lista de adyacencia, pero también almacenan una columna "root_id". Cada miembro de un árbol determinado tiene el mismo valor para root_id, que es el nodo antecesor más alto de su árbol. Entonces es fácil obtener un árbol completo en una sola consulta:

SELECT * FROM site WHERE root_id = 123;

Luego, su aplicación recupera todos los nodos de la base de datos en una matriz, y debe escribir el código para recorrer esta matriz, insertando los nodos en una estructura de datos de árbol en la memoria. Esta es una buena solución si tiene muchos árboles separados y cada árbol tiene relativamente pocas entradas. Es bueno para el caso de Slashdot.