2011-02-05 6 views
5

Estoy diseñando una base de datos y tengo algunas dudas sobre el uso de modelos de datos jerárquicos en bases de datos relacionales.Design Relational Database - ¿Utiliza modelos de datos jerárquicos o los evita?

Si quiero tratar con categorías, subcategorías y categorías principales, ¿es posible no usar un modelo de datos jerárquico en una base de datos relacional? En otras palabras, es posible tratar con categorías, subcategorías y categorías principales utilizando la forma relacional de hacer las cosas.

Por cierto, estoy usando PostgreSQL.

Lo siento por mi mal inglés.

Best Regards,

+0

Consulte esta pregunta para obtener una lista de opciones, lecturas adicionales y costos de notas de acciones como la recuperación de antepasados ​​y los tiempos de inserción de nodos: http://stackoverflow.com/questions/4048151/what-are-the-options-for -storing-hierarchical-data-in-a-relational-database – orangepips

Respuesta

18

usted tiene un par de opciones para almacenar las jerarquías:

  • lista de adyacencia
  • recursiva de la consulta en una lista adjancy
  • Ruta Enumeración
  • anidada Establece
  • Cierre Tabla

Si tiene PostgreSQL versión 8.4 o la ter, puede usar recusive queries para hacer las cosas más fáciles. Esta es, de lejos, la solución más fácil, fácil de consultar, fácil de insertar nuevos registros, fácil de actualizar registros actuales, fácil de eliminar registros y tiene integridad referencial. Todas las otras soluciones tienen partes que son difíciles de resolver.

lista Adjency:

CREATE TABLE categories ( 
    id SERIAL PRIMARY KEY, 
    parent_id BIGINT, 
    category TEXT NOT NULL, 
    FOREIGN KEY (parent_id) REFERENCES categories(id) 
); 

INSERT INTO categories(parent_id, category) VALUES(NULL, 'vehicles'); 
INSERT INTO categories(parent_id, category) VALUES(1, 'cars'); 
INSERT INTO categories(parent_id, category) VALUES(1, 'motorcycles'); 
INSERT INTO categories(parent_id, category) VALUES(2, 'SUV'); 
INSERT INTO categories(parent_id, category) VALUES(2, 'sport'); 
INSERT INTO categories(parent_id, category) VALUES(3, 'cruising'); 
INSERT INTO categories(parent_id, category) VALUES(3, 'sport'); 


WITH RECURSIVE tree (id, parent_id, category, category_tree, depth) 
AS ( 
    SELECT 
     id, 
     parent_id, 
     category, 
     category AS category_tree, 
     0 AS depth 
    FROM categories 
    WHERE parent_id IS NULL 
UNION ALL 
    SELECT 
     c.id, 
     c.parent_id, 
     c.category, 
     tree.category_tree || '/' || c.category AS category_tree, 
     depth+1 AS depth 
    FROM tree 
     JOIN categories c ON (tree.id = c.parent_id) 
) 
SELECT * FROM tree ORDER BY category_tree; 

Resultado:

'1', '', 'vehículo', 'vehículo', '0'

'2', '1 ', 'automóviles', 'vehículo/coches', '1'

'4', '2', 'SUV', 'vehículo/coches/SUV', '2'

'5', '2', 'deporte', 'vehículo/automóviles/deporte', '2'

'3', '1', 'motocicletas', 'vehículo/motocicletas', '1'

'6', '3', 'crucero', 'vehículo/motocicletas/crucero', '2'

'7', '3', 'deporte', 'vehículo/motocicletas/deporte', '2'

+0

+1 para señalar consultas recursivas (que son compatibles con una amplia gama de DBMS hoy en día) –

+0

Muy buen ejemplo de cómo recuperar una jerarquía y profundidad de filas. La profundidad se puede usar para hacer un tipo topológico (PEDIDO POR profundidad). –

+0

¡Gran respuesta! ¡gracias! –

-1

¿Qué quiere decir por "modelo de datos jerárquico"? Si solo quiere decir modelar una jerarquía en una base de datos relacional o SQL, entonces eso es algo perfectamente común y razonable de hacer. Existe una cantidad significativa de literatura de bases de datos sobre el tema de cómo modelar las jerarquías relacionalmente. No hay nada "no relacional" sobre hacer eso.

Sin embargo, el término datos jerárquicos Modelo más general, se refiere a un tipo de DBMS (no un RDBMS o DBMS SQL). Los DBMS jerárquicos/de red/gráficos operan según principios diferentes a los RDBMS: utilizan modelos de navegación o basados ​​en punteros en lugar del modelo relacional. El modelo relacional/SQL ha reemplazado en gran medida (pero no del todo) ese tipo de DBMS. A menos que esté utilizando un tipo jerárquico de DBMS, entonces no necesita preocuparse por ello.

1

Si está utilizando Postgres, puede almacenar la jerarquía en una matriz como materialized path.

También se beneficia de la indexación de GIN con este enfoque, que en mis experimentos ha tenido un mejor rendimiento que una consulta recursiva.

+0

¿cómo crearías un índice GIN para dicha columna? – EdMelo

+1

De la misma manera que crearía cualquier índice anterior: 'CREATE INDEX name ON table USANDO gin (column);' (https://www.postgresql.org/docs/9.5/static/textsearch-indexes.html) –

Cuestiones relacionadas