mysql - tablas - ¿Cuáles son las diferencias en estos ejemplos de tabla de cierre de SQL?
left join mysql ejemplos (0)
Tengo algunas dificultades para pensar en las tablas de cierre de SQL y me gustaría obtener ayuda para entender algunos de los ejemplos que he encontrado.
Digamos que tengo una tabla llamada sample_items
con los siguientes datos jerárquicos:
id name parent_id
1 ''Root level item #1'' 0
2 ''Child of ID 1'' 1
3 ''Child of ID 2'' 2
4 ''Root level item #2'' 0
La estructura del árbol debería ser efectivamente esta:
id
| - 1
| | - 2
| | - 3
| - 4
Para facilitar la consulta de los árboles (como encontrar todos los descendientes de un ID específico), tengo una tabla llamada sample_items_closure
utiliza el método descrito por Bill Karwin en esta excelente publicación SO . También uso una columna path_length
opcional para consultar al hijo o padre inmediato cuando sea necesario. Si entiendo este método correctamente, los datos de mi tabla de cierre serían así:
ancestor_id descendant_id path_length
1 1 0
2 2 0
1 2 1
3 3 0
2 3 1
1 3 2
4 4 0
Cada fila en sample_items
ahora tiene una entrada en la tabla sample_items_closure
tanto para sí misma como para todos sus antepasados. Todo tiene sentido hasta ahora.
Mientras estudiaba otros ejemplos de tablas de cierre, sin embargo, encontré uno que agrega un ancestro adicional para cada fila que enlaza con el nivel raíz (ancestor_id 0) y tiene una longitud de ruta de 0. Usando los mismos datos que tengo arriba, esto es lo la mesa de cierre se vería así:
ancestor_id descendant_id path_length
1 1 0
0 1 0
2 2 0
1 2 1
0 2 0
3 3 0
2 3 1
1 3 2
0 3 0
4 4 0
0 4 0
Para dar un mejor contexto, aquí hay una consulta de selección utilizada en ese sitio, modificada para que se ajuste a mis ejemplos:
SELECT `id`,`parent_id` FROM `sample_items` `items`
JOIN `sample_items_closure` `closure`
ON `items`.`id` = `closure`.`descendant_id`
WHERE `closure`.`ancestor_id` = 2
Tengo dos preguntas relacionadas con este método:
Pregunta 1:
¿Por qué se agregaría una fila adicional que vincule cada descendiente al nivel raíz (id 0)?
Pregunta 2:
¿Por qué path_length sería 0 para estas entradas, en lugar de ser path_length + 1 del antecesor anterior? Por ejemplo:
ancestor_id descendant_id path_length
1 1 0
0 1 1
2 2 0
1 2 1
0 2 2
3 3 0
2 3 1
1 3 2
0 3 3
4 4 0
0 4 1
Pregunta de bonificación : ¿Por qué algunos ejemplos aún incluyen una lista de adyacencia (la columna sample_items
para sample_items
en mi ejemplo) cuando la estructura completa del árbol ya está expresada en la tabla de cierre?