2011-08-18 6 views
9

¿Hay alguna herramienta que funcione con SQL Server para generar diagramas tipo árbol a partir de un modelo de datos jerárquicos?¿Qué herramienta genera diagramas a partir de datos jerárquicos de SQL Server?

Estoy trabajando con una gran jerarquía geográfica y me gustaría visualizarla.

Aquí hay un ejemplo.

Tengo una tabla NodeHierarchy que almacena una relación jerárquica entre los nodos. Cada fila en la tabla representa un nodo. Cada nodo, excepto uno, tiene un nodo padre. El nodo que no tiene padre es la raíz si la jerarquía.

Así es como puedo crear mi mesa:

CREATE DATABASE HierarchyTest; 
GO 

USE HierarchyTest; 
GO 

CREATE TABLE NodeHierarchy (
    PK_NodeID INT NOT NULL 
    CONSTRAINT PK_NodeHierarchy PRIMARY KEY, 
    FK_ParentNodeID INT NULL 
    CONSTRAINT FK_NodeHierarchy_NodeHierarchy FOREIGN KEY 
     REFERENCES NodeHierarchy(PK_NodeID), 
    Name NVARCHAR(255) NOT NULL 
); 

Tengo un ejemplo de jerarquía de ciudades y lugares de Escocia. Escocia es la raíz de la jerarquía. Los descendientes de Escocia son ciudades y lugares. En esta jerarquía, un padre "contiene" un hijo, por lo que decimos que, por ejemplo, "The Barrowlands está en Glasgow, y Glasgow está en Escocia".

Esta declaración rellena la tabla NodeHierachy con los datos eample:

INSERT INTO NodeHierarchy(PK_NodeID, FK_ParentNodeID, Name) 
VALUES 
    (1, NULL, N'Scotland'), 
    (2, 1, N'Glasgow'), 
    (3, 1, N'Edinburgh'), 
    (4, 1, N'St Andrews'), 
    (5, 2, N'The Barrowlands'), 
    (6, 2, N'The Cathouse'), 
    (7, 2, N'Carling Academy'), 
    (8, 2, N'SECC'), 
    (9, 2, N'King Tut''s Wah-Wah Hut'), 
    (10, 3, N'Henry''s Cellar Bar'), 
    (11, 3, N'The Bongo Club'), 
    (12, 3, N'Sneaky Pete''s'), 
    (13, 3, N'The Picture House'), 
    (14, 3, N'Potterrow'), 
    (15, 4, N'Aikman''s'), 
    (16, 4, N'The Union'), 
    (17, 4, N'Castle Sands'); 

salida de SELECT * FROM NodeHierarchy;:

PK_NodeID FK_ParentNodeID Name 
----------- --------------- --------------------------------- 
1   NULL   Scotland 
2   1    Glasgow 
3   1    Edinburgh 
4   1    St Andrews 
5   2    The Barrowlands 
6   2    The Cathouse 
7   2    Carling Academy 
8   2    SECC 
9   2    King Tut's Wah-Wah Hut 
10   3    Henry's Cellar Bar 
11   3    The Bongo Club 
12   3    Sneaky Pete's 
13   3    The Picture House 
14   3    Potterrow 
15   4    Aikman's 
16   4    The Union 
17   4    Castle Sands 

(17 row(s) affected) 

En Freemind hice este esquema equivalente: mindmap of Scottish venues

Qué herramienta puede hacer esto para mí con un mínimo de esfuerzo manual?


EDIT: principio yo dije que quería para visualizar "todo o parte" de la jerarquía. La solución publicada aquí visualiza toda la jerarquía incondicionalmente. Esto está bien para la jerarquía de ejemplos pequeños, pero para una jerarquía más grande, puede ser más útil visualizar solo una parte de ella.

Como no especifiqué lo que quise decir con "parte", lo eliminé de la pregunta. He preguntado sobre la visualización parcial en another question.

+0

+1 Esta es una gran pregunta. Me gustaría saber la respuesta también. –

+0

+1 Me gusta mucho que hayas incluido 'CREATE DATABASE' y' INSERT' para que pueda cortar y pegar. –

+0

Gracias, Kirk. Está en el espíritu del 'ejemplo corto, autónomo, correcto y compilable': http://sscce.org/. –

Respuesta

6

Investigué los clientes potenciales en la respuesta de Cade Roux y desarrollé una solución usando GraphViz.

Para entender GraphViz, primero leo este introductory article y la documentación Command-line Invocation. Después de generar con éxito gráficos del listado de código de ejemplo en el artículo, me sentí seguro de trabajar con mis propios datos.

Como sugirió Cade, la mejor manera de aprender el lenguaje DOT de GraphViz es escribirlo yo mismo. Estudié ejemplos del artículo (Listados 1, 2, y 6) y luego ocurrió esta venues.gv para describir mi propia datos:

digraph Venues 
{ 
    N1[label = "Scotland"]; 
    N2[label = "Glasgow"]; 
    N3[label = "Edinburgh"]; 
    N4[label = "St Andrews"]; 
    N5[label = "The Barrowlands"]; 
    N6[label = "The Cathouse"]; 
    N7[label = "Carling Academy"]; 
    N8[label = "SECC"]; 
    N9[label = "King Tut's Wah-Wah Hut"]; 
    N10[label = "Henry's Cellar Bar"]; 
    N11[label = "The Bongo Club"]; 
    N12[label = "Sneaky Pete's"]; 
    N13[label = "The Picture House"]; 
    N14[label = "Potterrow"]; 
    N15[label = "Aikman's"]; 
    N16[label = "The Union"]; 
    N17[label = "Castle Sands"]; 

    N1 -> N2; 
    N1 -> N3; 
    N1 -> N4; 
    N2 -> N5; 
    N2 -> N6; 
    N2 -> N7; 
    N2 -> N8; 
    N2 -> N9; 
    N3 -> N10; 
    N3 -> N11; 
    N3 -> N12; 
    N3 -> N13; 
    N3 -> N14; 
    N4 -> N15; 
    N4 -> N16; 
    N4 -> N17; 
} 

di de comer esto a circo, sólo uno de los muchos comandos gráfico-dibujo que son parte de GraphViz, y tiene salida agradable:

salida de circo -Tpng venues.gv -o venues.png:

Visualization of hierarchical venue data

El archivo GraphViz se estructura en dos bloques. Un bloque declara una etiqueta para cada nodo, y el otro bloque declara los bordes del gráfico.

Para proporcionar los datos de cada uno de estos bloques, creé una vista de NodeHierarchy.

Esta vista proporciona los datos para declarar etiquetas para los nodos:

CREATE VIEW NodeLabels (
    Node, 
    Label 
) 
AS 
SELECT 
    PK_NodeID AS Node, 
    Name AS Label 
FROM 
    NodeHierarchy; 

Esta vista proporciona los datos para declarar bordes entre nodos:

CREATE VIEW Edges (
    Parent, 
    Child 
) 
AS 
SELECT 
    FK_ParentNodeID AS Parent, 
    PK_NodeID AS Child 
FROM NodeHierarchy 
WHERE FK_ParentNodeID IS NOT NULL; 

Este script Powershell llamado generate-graph.ps1 selecciona los datos de la vistas, lo transforma en una entrada GraphViz y lo canaliza al circo para producir una visualización de la jerarquía completa como la de arriba:

"digraph Venues {" + (
    Invoke-Sqlcmd -Query "SELECT * FROM HierarchyTest.dbo.NodeLabels" | 
    ForEach-Object {"N" + $_.Node + "[label = """ + $_.Label + """];"} 
) + (
    Invoke-Sqlcmd -Query "SELECT * FROM HierarchyTest.dbo.Edges" | 
    ForEach-Object {"N" + $_.Parent + " -> N" + $_.Child + ";"} 
) + 
"}" | circo -Tpng -o venues.png 

La secuencia de comandos se debe ejecutar en sqlps en lugar de powershell de modo que el cmdlet Invoke-Sqlcmd esté disponible. El directorio de trabajo predeterminado de sqlps es SQLSERVER, por lo que debo especificar el disco cuando ejecuto el script a través del sqlps.

Este es el comando que utilizo para generar un gráfico como el de arriba:

sqlps C:.\generate-graph.ps1 

Esto genera un archivo llamado venues.png en el directorio de trabajo C.

Esta solución Powershell se siente un poco poco elegante, pero esto hace lo que necesito hacer. Un programador de Powershell con más experiencia podría encontrar algo más limpio.

+0

Esto visualiza solo toda la jerarquía. Para mi pequeño conjunto de datos de muestra, esto está bien, pero para un conjunto más grande de datos podría querer mirar solo una pequeña parte de la jerarquía. Publicaré una solución actualizada que hace esto posible. –

7

Exportar y ejecutar a través de GraphViz - ni siquiera tiene que generar la jerarquía (solo exportar nodos y bordes) - simplemente asigne nombres de nodo que son únicos basados ​​en su columna NodeID y use esos mismos nombres de nodo en los bordes .

Si desea algo interactivo, Microsoft tiene un Automatic Graph Layout library que se puede utilizar desde .NET.

Aquí hay un introduction to GraphViz.

Lo que vas a hacer es generar un archivo DOT exportando tu SQL usando un script como este: http://data.stackexchange.com/stackoverflow/q/109885/ que se ejecutará a través de GraphViz y generará tu imagen.

La sintaxis DOT es relativamente simple: puede escribirla primero a mano y luego generarla desde SQL y simplemente pegarla en un archivo u otra cosa (como .NET o PowerShell) que lea los conjuntos SQL y genere el archivo .

Puede automatizar eso con SSIS.Hice un paquete que escribió el archivo DOT, lo gravé y guardé una instantánea grafica de nuestro sistema a diario.

+0

No estoy familiarizado con GraphViz, y no sé a qué te refieres con 'exportar'. ¿Puedes explicar el proceso con más detalle? ¡Gracias! –

+0

@isme He agregado algunos punteros más –

+0

Leí la introducción, escrita en 2004. La versión 2.28 de GraphViz produce resultados diferentes en algunos de los listados de códigos de la versión utilizada por el autor, pero aún funcionan y son un gran aprendizaje ayuda. ¡Gracias! –

Cuestiones relacionadas