Buenas descripciones
En términos generales, está tomando una decisión entre tiempos de lectura rápidos (por ejemplo, conjunto anidado) o tiempos de escritura rápidos (lista de adyacencia). Por lo general, terminas con una combinación de las siguientes opciones que mejor se adaptan a tus necesidades. Lo siguiente proporciona una lectura en profundidad:
- Una comparación más de Intervalos anidados versus Lista de adyacencia : la mejor comparación de Lista de adyacencia, Ruta materializada, Conjunto anidado e Intervalo anidado que he encontrado.
- Modelos para datos jerárquicos : diapositivas con buenas explicaciones de compensaciones y ejemplos de uso.
- Representación de jerarquías en MySQL : muy buena visión general de Nested Set en particular
- Datos jerárquicos en RDBMS : conjunto de enlaces más completo y bien organizado que he visto, pero no hay mucha explicación
Opciones
Los que conozco y las características generales:
- Lista de adyacencia :
- Columnas: ID, ParentID
- Fácil de implementar.
- El nodo barato se mueve, inserta y elimina.
- Caro para encontrar el nivel, ascendencia y descendientes, camino
- Evite N + 1 a través de expresiones de tabla comunes en bases de datos que las admiten
- Conjunto anidado (también conocido como Recorrido de árbol de pedido anticipado modificado )
- Columnas: izquierda, derecha
- Ascendencia barata, descendientes
- Movimientos
O(n/2)
, inserciones y eliminaciones muy costosas debido a la codificación volátil
- Tabla de puente (también conocida como Tabla de cierre / desencadenantes w )
- Utiliza una tabla de unión separada con: ancestro, descendiente, profundidad (opcional)
- Ascendencia barata y descendientes
- Escribe los costos
O(log n)
(tamaño del subárbol) para insertar, actualizar, eliminar - Codificación normalizada: buena para estadísticas RDBMS y planificador de consultas en combinaciones
- Requiere varias filas por nodo
- Columna de linaje (también conocido como Ruta materializada , Enumeración de ruta)
- Columna: linaje (p. Ej. / Padre / hijo / nieto / etc.)
- Descendientes baratos a través de la consulta de prefijo (por ejemplo
LEFT(lineage, #) = '/enumerated/path'
) - Escribe los costos
O(log n)
(tamaño del subárbol) para insertar, actualizar, eliminar - No relacional: se basa en el tipo de datos de matriz o el formato de cadena serializada
- Intervalos anidados
- Al igual que el conjunto anidado, pero con real / flotante / decimal para que la codificación no sea volátil (movimiento / inserción / eliminación de bajo costo)
- Tiene problemas de representación real / flotante / decimal / precisión
- La variante de codificación de matriz agrega codificación ancestral (ruta materializada) para "libre", pero con truco adicional de álgebra lineal.
- Mesa plana
- Una Lista de adyacencia modificada que agrega una columna de Nivel y Rango (por ejemplo, ordenar) a cada registro.
- Barato para iterar / paginar
- Movimiento costoso y eliminar
- Buen uso: discusión con hilos - foros / comentarios de blog
- Múltiples columnas de linaje
- Columnas: una para cada nivel de linaje, se refiere a todos los padres hasta la raíz, los niveles inferiores al nivel del elemento se establecen en NULL
- Antepasados baratos, descendientes, nivel
- Inserto barato, eliminar, mover las hojas
- Costoso insertar, eliminar, mover los nodos internos
- Límite estricto de cuán profunda puede ser la jerarquía
Notas específicas de la base de datos
MySQL
Oráculo
- Use CONNECT BY para recorrer las listas de adyacencia
PostgreSQL
- tipo de datos ltree para ruta materializada
servidor SQL
- Resumen general
- 2008 ofrece que el tipo de datos HierarchyId parece ayudar con el enfoque de la columna de linaje y ampliar la profundidad que se puede representar.
Closure Tables
son superiores aAdjacency List
,Path Enumeration
yNested Sets
en términos de facilidad de uso (y supongo rendimiento, así).