ventajas jerarquico jerarquicas jerarquica informatica estructura ejemplos desventajas definicion datos busqueda arboles arbol sql sqlite tree hierarchical-data

sql - jerarquico - base de datos jerárquica/de árbol para directorios en sistema de archivos



jerarquicas (3)

Aquí hay un ejemplo de tabla de cierre rápido para SQLite. No he incluido las declaraciones para insertar elementos en un árbol existente. En cambio, acabo de crear las declaraciones de forma manual. Puede encontrar las instrucciones de inserción y eliminación en los Modelos para diapositivas de datos jerárquicos .

Por el bien de mi cordura al insertar los ID para los directorios, cambié el nombre de los directorios para que coincidan con sus ID:

(ROOT) / / Dir2 Dir3 / / / Dir4 Dir5 Dir6 / Dir7

Crear tablas

CREATE TABLE `filesystem` ( `id` INTEGER, `dirname` TEXT, PRIMARY KEY (`id`) ); CREATE TABLE `tree_path` ( `ancestor` INTEGER, `descendant` INTEGER, PRIMARY KEY (`ancestor`, `descendant`) );

Insertar directorios en la tabla del filesystem

INSERT INTO filesystem (id, dirname) VALUES (1, ''ROOT''); INSERT INTO filesystem (id, dirname) VALUES (2, ''Dir2''); INSERT INTO filesystem (id, dirname) VALUES (3, ''Dir3''); INSERT INTO filesystem (id, dirname) VALUES (4, ''Dir4''); INSERT INTO filesystem (id, dirname) VALUES (5, ''Dir5''); INSERT INTO filesystem (id, dirname) VALUES (6, ''Dir6''); INSERT INTO filesystem (id, dirname) VALUES (7, ''Dir7'');

Crear las rutas de la tabla de cierre

INSERT INTO tree_path (ancestor, descendant) VALUES (1, 1); INSERT INTO tree_path (ancestor, descendant) VALUES (1, 2); INSERT INTO tree_path (ancestor, descendant) VALUES (1, 3); INSERT INTO tree_path (ancestor, descendant) VALUES (1, 4); INSERT INTO tree_path (ancestor, descendant) VALUES (1, 5); INSERT INTO tree_path (ancestor, descendant) VALUES (1, 6); INSERT INTO tree_path (ancestor, descendant) VALUES (1, 7); INSERT INTO tree_path (ancestor, descendant) VALUES (2, 2); INSERT INTO tree_path (ancestor, descendant) VALUES (2, 4); INSERT INTO tree_path (ancestor, descendant) VALUES (2, 5); INSERT INTO tree_path (ancestor, descendant) VALUES (2, 7); INSERT INTO tree_path (ancestor, descendant) VALUES (3, 3); INSERT INTO tree_path (ancestor, descendant) VALUES (3, 6); INSERT INTO tree_path (ancestor, descendant) VALUES (4, 4); INSERT INTO tree_path (ancestor, descendant) VALUES (4, 7); INSERT INTO tree_path (ancestor, descendant) VALUES (5, 5); INSERT INTO tree_path (ancestor, descendant) VALUES (6, 6); INSERT INTO tree_path (ancestor, descendant) VALUES (7, 7);

Ejecuta algunas consultas

# (ROOT) and subdirectories SELECT f.id, f.dirname FROM filesystem f JOIN tree_path t ON t.descendant = f.id WHERE t.ancestor = 1; +----+---------+ | id | dirname | +----+---------+ | 1 | ROOT | | 2 | Dir2 | | 3 | Dir3 | | 4 | Dir4 | | 5 | Dir5 | | 6 | Dir6 | | 7 | Dir7 | +----+---------+ # Dir3 and subdirectories SELECT f.id, f.dirname FROM filesystem f JOIN tree_path t ON t.descendant = f.id WHERE t.ancestor = 3; +----+---------+ | id | dirname | +----+---------+ | 3 | Dir3 | | 6 | Dir6 | +----+---------+ # Dir5 and parent directories SELECT f.id, f.dirname FROM filesystem f JOIN tree_path t ON t.ancestor = f.id WHERE t.descendant = 5; +----+---------+ | id | dirname | +----+---------+ | 1 | ROOT | | 2 | Dir2 | | 5 | Dir5 | +----+---------+ # Dir7 and parent directories SELECT f.id, f.dirname FROM filesystem f JOIN tree_path t ON t.ancestor = f.id WHERE t.descendant = 7; +----+---------+ | id | dirname | +----+---------+ | 1 | ROOT | | 2 | Dir2 | | 4 | Dir4 | | 7 | Dir7 | +----+---------+ SELECT f.id, f.dirname FROM filesystem f JOIN tree_path t ON t.ancestor = f.id WHERE t.descendant = ( SELECT id FROM filesystem WHERE dirname LIKE ''%7%'' ); +----+---------+ | id | dirname | +----+---------+ | 1 | ROOT | | 2 | Dir2 | | 4 | Dir4 | | 7 | Dir7 | +----+---------+

Quiero almacenar los directorios presentes en el disco en una base de datos con el mantenimiento de su estructura jerárquica / árbol.

Aquí hay una figura,

(ROOT) / / Dir2 Dir3 / / / Dir4 Dir5 Dir6 / Dir7

Estoy usando la base de datos SQLite .

  • Por favor sugiérame la consulta SQL para almacenar la estructura anterior en la base de datos SQLite.

  • y una consulta para recuperar la ruta completa del directorio cuando selecciono uno.

es decir, supongamos que selecciono Dir6, entonces podría obtener la ruta completa como ROOT / Dir2 / dir3 / dir7


Creo que deberías leer acerca de un método llamado Modificado Preorden Tree Traversal : http://www.sitepoint.com/hierarchical-data-database/

Ese enlace trata sobre dos métodos para almacenar datos jerárquicos en bases de datos relacionales: el modelo de lista de adyacencia y el algoritmo de cruce de árbol de preordenamiento modificado.

La idea principal del método Modified Preorder Tree Traversal es anotar todos los nodos con punteros para ayudar a la navegación y la selección de subárbol:


Usted representa los datos jerárquicos como una serie de nodos, cada uno de los cuales tiene un ID y un Parent ID. Puede almacenarlo en una tabla llamada DIRTAB con 2 columnas ID y una para el texto del nombre del directorio individual:

ID -- as a primary key PARENT_ID -- refers to the ID of the parent row in DIRTAB DIRNAME -- the text of the name eg Dir5

SQLite carece de la cláusula CONNECT BY de que Oracle tiene que procesar los datos jerárquicos, pero creo que si está preparado para aceptar algunos SQL desagradables, puede aproximarse a algo jerárquico:

SELECT (CASE WHEN p5.DIRNAME IS NOT NULL THEN p5.DIRNAME || ''/'' ELSE '''' END) || (CASE WHEN p4.DIRNAME IS NOT NULL THEN p4.DIRNAME || ''/'' ELSE '''' END) || (CASE WHEN p3.DIRNAME IS NOT NULL THEN p3.DIRNAME || ''/'' ELSE '''' END) || (CASE WHEN p2.DIRNAME IS NOT NULL THEN p2.DIRNAME || ''/'' ELSE '''' END) || (CASE WHEN p1.DIRNAME IS NOT NULL THEN p1.DIRNAME || ''/'' ELSE '''' END) || p0.DIRNAME as FULLPATH FROM DIRTAB p0 LEFT OUTER JOIN DIRTAB p1 ON p1.ID = p0.PARENT_ID LEFT OUTER JOIN DIRTAB p2 ON p2.ID = p1.PARENT_ID LEFT OUTER JOIN DIRTAB p3 ON p3.ID = p2.PARENT_ID LEFT OUTER JOIN DIRTAB p4 ON p4.ID = p3.PARENT_ID LEFT OUTER JOIN DIRTAB p5 ON p5.ID = p4.PARENT_ID WHERE p0.DIRNAME = ''Dir6''

El problema aquí es que debe anticipar la profundidad máxima de su estructura de directorios y expandir la declaración SQL para hacer frente. He hecho 6 niveles como un ejemplo.
También asumo que SQLite no tiene problemas para concatenar cadenas vacías. (Algunos DB los tratan como nulos y convierten el resultado de la expresión completa en nulo)