是否有一个可与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
);
我有一个苏格兰城市和场所的层级示例。苏格兰是等级制的根源。苏格兰的后裔是城市和场馆。在这个课程中,父母“包含”了一个孩子,所以我们这样说。 “巴罗兰在格拉斯哥,而格拉斯哥在苏格兰”。
该语句使用示例数据填充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中,我绘制了以下等效图:
什么样的工具可以用最少的人工为我做到这一点?
编辑:最初我说过,我想可视化层次结构的“全部或部分”。此处发布的解决方案无条件可视化整个层次结构。这对于较小的示例层次结构很好,但是对于较大的示例层次结构,仅可视化其中的一部分可能会更有用。
因为我没有指定“部件”的含义,所以已将其从问题中删除。我曾问过another question中的部分可视化。
最佳答案
我研究了Cade Roux答案中的线索,并使用GraphViz开发了解决方案。
为了理解GraphViz,首先我阅读了introductory article和Command-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
的输出: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程序员也许可以提出更简洁的建议。