什么工具从SQL Server分层数据生成图表?

时间:2011-08-18 17:20:21

标签: sql-server visualization hierarchical-data diagramming

是否有适用于SQL Server的工具可以从分层数据模型生成类似树的图表?

我正在处理大型地理层次结构,并希望将其可视化。

这是一个例子。

我有一个NodeHierarchy表,用于存储节点之间的层次关系。表中的每一行代表一个节点。除一个节点外,每个节点都有一个父节点没有父节点的节点是层次结构的根。

以下是我创建表格的方法:

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
);

我有一个苏格兰城市和场地的例子。苏格兰是层次结构的根源。苏格兰的后裔是城市和场所。在这个家庭中,父母“包含”一个孩子,所以我们说,例如“巴罗兰地区位于格拉斯哥,格拉斯哥位于苏格兰”。

此语句使用eample数据填充NodeHierachy表:

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');

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)

Freemind中我绘制了这个等效图: mindmap of Scottish venues

使用最少的手动工作,什么工具可以为我做到这一点?


编辑:最初我说我想要想象层次结构的“全部或部分”。此处发布的解决方案无条件地显示整个层次结构。这适用于小的示例层次结构,但对于较大的示例层次结构,仅可视化其中的一部分可能更有用。

因为我没有说明“部分”的含义,所以我已经从问题中删除了这一点。我在another question中询问了部分可视化。

2 个答案:

答案 0 :(得分:8)

导出并运行GraphViz - 您甚至不必生成层次结构(只是导出节点和边缘) - 只需根据NodeID列分配唯一的节点名称并使用相同的节点名称在边缘。

如果你想要一些交互式的东西,微软有一个Automatic Graph Layout library可以在.NET中使用。

这是一个introduction to GraphViz

您要做的是通过使用以下脚本导出SQL来输出DOT文件:http://data.stackexchange.com/stackoverflow/q/109885/将运行GraphViz并生成您的图片。

DOT语法相对简单 - 您可以先手动编写它,然后从SQL生成它,只需将其粘贴到一个文件或其他东西(如.NET或PowerShell)中,它们会读取SQL集并生成文件。

您可以使用SSIS自动执行此操作。我制作了一个包写了DOT文件并在其上运行graphviz并每天保存我们系统的图形快照。

答案 1 :(得分:8)

我研究了Cade Roux的答案中的线索,并使用GraphViz开发了一个解决方案。

要了解GraphViz,请先阅读此introductory articleCommand-line Invocation文档。在从文章中的示例代码列表中成功生成图表后,我有信心使用自己的数据。

正如Cade所说,学习GraphViz的DOT语言的最好方法是自己写出来。我研究了文章的例子(清单1,2和6),然后提出了这个venues.gv来描述我自己的数据:

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;
}

我将它提供给circo,只是GraphViz中许多图形绘制命令之一,并获得了令人满意的输出:

circo -Tpng venues.gv -o venues.png的输出:

Visualization of hierarchical venue data

GraphViz文件由两个块组成。一个块为每个节点声明一个标签,另一个块声明图形的边缘。

为了提供每个块的数据,我创建了NodeHierarchy的视图。

此视图提供声明节点标签的数据:

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

此视图提供了在节点之间声明边的数据:

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

这个名为generate-graph.ps1的Powershell脚本从视图中选择数据,将其转换为GraphViz输入,并将其传递给circo以生成完整层次结构的可视化,如上所示:

"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

该脚本必须在sqlps而不是powershell中运行,以便Invoke-Sqlcmd cmdlet可用。 sqlps的默认工作目录为SQLSERVER,因此我必须在通过sqlps运行脚本时指定驱动器。

这是我用来生成如上图所示的命令:

sqlps C:.\generate-graph.ps1

这将在C工作目录中输出名为venues.png的文件。

这款Powershell解决方案感觉有点不雅,但这就是我需要它做的事情。一个更有经验的Powershell程序员可能会想出更清洁的东西。