【问题标题】:What tool generates diagrams from SQL Server hierarchical data?什么工具从 SQL Server 分层数据生成图表?
【发布时间】:2011-10-30 00:01:30
【问题描述】:

是否有工具可以与 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 中询问了关于部分可视化的问题。

【问题讨论】:

  • +1 这是一个很好的问题。我也想知道答案。
  • +1 我真的很喜欢你添加了CREATE DATABASE 和INSERT 这样我就可以剪切和粘贴了!
  • 谢谢,柯克。它的精神是“简短、独立、正确、可编译的示例”:sscce.org。

标签: sql-server visualization hierarchical-data diagramming


【解决方案1】:

我研究了 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 程序员可能会想出一些更干净的东西。

【讨论】:

  • 这只可视化整个层次结构。对于我的小样本数据集,这很好,但对于更大的数据集,我可能只想查看层次结构的一小部分。我将发布一个更新的解决方案,使这成为可能。
【解决方案2】:

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

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

这是introduction to GraphViz。

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

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

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

【讨论】:

  • 我对 GraphViz 不熟悉,也不知道您所说的“导出”是什么意思。你能更详细地解释一下这个过程吗?谢谢!
  • 我阅读了 2004 年编写的介绍。GraphViz 2.28 版在一些代码清单上产生了与作者使用的版本不同的输出,但它们仍然有效并且是一个很好的学习帮助。谢谢!
  • 您是如何在 SSIS 中实现写出 DOT 文件的?我只能输出平面文件。如果不使用脚本任务,我看不到任何输出 DOT 文件的方法。
  • @isme 您可以使用以下方式从 SQL proc 生成一组“行”:SELECT * FROM (SELECT '01-header' AS section, 1 AS line_num, 'digraph g' AS line UNION ALL SELECT '01-header' AS section, 2 AS line_num, '{' AS line UNION ALL SELECT '02-body' AS section, ROW_NUMBER() OVER (ORDER BY nodeid) AS line_num, 'node' + nodeid AS line FROM nodes UNION ALL ...) ORDER BY section, line_number - 现在您有了“行”的有序输出,只需编写“行”列作为平面文件中的行。或者编写一个平面文件并在前面/附加一个批处理文件或其他任何东西。
  • 感谢 SSIS 的诡计,但与此同时,我编写了一个 Powershell 脚本来实现同样的目的。我将发布我的整个解决方案作为答案。
猜你喜欢
  • 2021-08-27
  • 2013-01-31
  • 1970-01-01
  • 1970-01-01
  • 2014-08-02
  • 1970-01-01
  • 2011-01-25
  • 1970-01-01
  • 2015-04-13
相关资源
最近更新 更多