¿Cuál es la mejor manera de construir la tabla que representará el árbol? Quiero implementar una selección, insertar, actualizar y eliminar que funcionará bien con Big Data. El seleccionar, por ejemplo, tendrá que admitir "Expandir TODOS" - obtener todos los niños (y los niños) para un nodo determinado.Cómo implementar la vista de árbol de alto rendimiento en SQL Server 2005
Respuesta
Use CTE
's.
Dada la estructura de la tabla en forma de árbol:
id parent name
1 0 Electronics
2 1 TV
3 1 Hi-Fi
4 2 LCD
5 2 Plasma
6 3 Amplifiers
7 3 Speakers
, esta consulta devolverá id
, parent
y la profundidad de nivel, ordenados como un árbol:
WITH v (id, parent, level) AS
(
SELECT id, parent, 1
FROM table
WHERE parent = 0
UNION ALL
SELECT id, parent, v.level + 1
FROM v
JOIN table t
ON t.parent = v.id
)
SELECT *
FROM v
id parent name
1 0 Electronics
2 1 TV
4 2 LCD
5 2 Plasma
3 1 Hi-Fi
6 3 Amplifiers
7 3 Speakers
Reemplazar parent = 0
con parent = @parent
para conseguir solamente una rama de un árbol.
Siempre que haya un índice en table (parent)
, esta consulta funcionará eficientemente en una tabla muy grande, ya que usará recursivamente INDEX LOOKUP
para encontrar todos los chilrden para cada padre.
Para actualizar una rama determinada, ejecuta:
WITH v (id, parent, level) AS
(
SELECT id, parent, 1
FROM table
WHERE parent = 0
UNION ALL
SELECT id, parent, v.level + 1
FROM v
JOIN table t
ON t.parent = v.id
)
UPDATE table t
SET column = newvalue
WHERE t.id IN
(
SELECT id
FROM v
)
donde @parent
es la raíz de la rama.
Consulte Joe Celko's book on trees and hierarchies para conocer múltiples formas de abordar el problema de la jerarquía. El modelo que elija dependerá de cómo pondere las búsquedas frente a las actualizaciones frente a la complejidad. Puede hacer las búsquedas bastante rápido (especialmente para obtener todos los elementos secundarios en un nodo) utilizando el modelo de lista de adyacencia, pero las actualizaciones del árbol son más lentas.
Gracias lo buscaré. ¿La unión es más eficiente que la recursiva? He oído que mssql 2005 tiene una nueva forma de tratar con árboles, ¿sabe si funciona bien con grandes DB? – SirMoreno
El UNION ALL dentro de un CTE es recursivo, aunque no estoy seguro de cómo SQL Server lo maneja detrás de escena o si hay ajustes de rendimiento en él. No he realizado suficientes pruebas a gran escala con CTE para asegurar mi rendimiento. –
Primero tiene que hacerse estas preguntas: 1) ¿Cuál es la proporción de modificaciones frente a lecturas? (= mayormente árbol estático o cambiando constantemente?) 2) ¿Qué tan profundo y qué tan grande esperas que crezca el árbol?
Los juegos anidados son ideales para árboles en su mayoría estáticos donde se necesitan operaciones en ramas enteras. Maneja árboles profundos sin problemas.
La trayectoria materializada funciona bien para árboles dinámicos (cambiantes) con profundidad limitada/predecible.
Los CTE recursivos son ideales para árboles muy pequeños, pero las operaciones de bifurcación ("obtener todos los niños en esta rama ...") se vuelven muy costosas con árboles grandes/profundos.
My Tree es muy dinámico, muchas actualizaciones pero muchas selecciones también. Y me gustaría poder profundizar en 10-15 niveles. Encontré este artículo sobre conjuntos anidados: http://sqlblog.com/blogs/adam_machanic/archive/2006/07/12/swinging-from-tree-to-tree-using-ctes-part-1-adjacency -to-nested-sets.aspx ¿Serán los conjuntos anidados como los descritos en este artículo mi mejor opción? gracias. – SirMoreno
Si tiene muchas actualizaciones y selecciona, la mejor opción parece ser la ruta de Enumeración de modelo, que se describe brevemente aquí:
http://www.sqlteam.com/article/more-trees-hierarchies-in-sql
Me sorprende que nadie ha mencionado ir con un Closure Table . Muy eficiente para leer y bastante simple de escribir.
- 1. MySQL vs SQL Server 2005/2008 rendimiento
- 2. ¿Cómo sé qué recomendaciones de índice de SQL Server 2005 implementar, si hay alguna?
- 3. SQL Server 2005 - Orden de combinaciones internas
- 4. SQL Server 2008 a SQL Server 2005
- 5. Cómo exportar la consulta de SQL Server 2005 a CSV
- 6. SQL Server 2005 replicación
- 7. Isoweek en SQL Server 2005
- 8. ¿Hay algún beneficio de rendimiento al usar SQL Server 2008 sobre SQL Server 2005?
- 9. DDD - Cómo implementar repositorios de alto rendimiento para buscar
- 10. Consultas jerárquicas en SQL Server 2005
- 11. SQL Server VIEW Rendimiento
- 12. ¿Dinámicamente nombrar índices en SQL Server 2005?
- 13. degradación de SQL Server 2008 a SQL Server 2005
- 14. ¿Cómo "declarar la variable escalar" en una vista en SQL Server (2005)
- 15. Cómo actualizar la resolución de conflictos al actualizar de SQL-Server 2005 a SQL-Server 2008
- 16. SQL Server 2005: cómo restar 6 meses
- 17. ¿Cómo encontrar los tipos de columna derivados de una vista en SQL Server 2005?
- 18. Extrayendo [] alrededor de la columna en SQL Server 2005
- 19. Extraer horas de DateTime (SQL Server 2005)
- 20. SQL Server 2008 Alto uso de CPU
- 21. Cómo debo usar BIT en SQL Server 2005
- 22. unen tres tablas en SQL Server 2005
- 23. Indexar varchar en MS SQL Server 2005
- 24. ¿Cómo se crean las plantillas de procedimientos almacenados de SQL Server 2005 en SQL Server 2005 Management Studio?
- 25. SQL Server 2005: interbloqueo de transacción
- 26. SQL Server 2005 pérdida de precisión numérica
- 27. Intercalación de clientes y SQL Server 2005
- 28. TransactionInDoubtException usando System.Transactions en SQL Server 2005
- 29. ¿Cómo implementar una aplicación de servidor de socket asíncrono de alto rendimiento en PHP?
- 30. subconsultas en UPDATE SET (sql server 2005)
¿Puede explicar la estructura de las tablas? ¿Esta consulta funcionará bien con un db grande? – SirMoreno
gracias, ¿Cómo puedo hacer una actualización profunda? - actualizar todos los nodos bajo un padre? (incluyendo a los nietos) – SirMoreno
hey, estoy tratando de hacer que esto funcione, y parece que el trabajo de dosent de vq funciona, lo estoy intentando en 2008.Además, ¿el nivel debe almacenarse en la base de datos, ya que no se muestra en la tabla? –