如何仅可视化层次结构中节点的后代、祖先和自身?
在另一个问题中,我询问了有关可视化存储的分层数据的问题在 SQL Server 数据库的表中。我找到了一种使用 GraphViz 以及 T-SQL 和 Powershell 中的一些管道来可视化整个层次结构的方法。
我想使用这样的可视化来调试使用类似数据的应用程序。对于小型示例层次结构来说,可视化一切都很好。但在数千人的等级制度中,这是压倒性的。
当我调试应用程序时,我通常只查看与给定节点相关的一小组节点。目前,对于给定节点,对我来说唯一重要的相关节点是后代和祖先,以及节点本身。
因此,我想要一种方法来仅可视化层次结构中作为给定节点的后代、祖先或自身的节点。
以下语句创建示例数据库和表,如链接问题中所示。
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
);
以下语句使用国家、城市和地点层次结构的修改版本填充表。英国现在是根节点,还有更多的节点代表英国著名场馆。
INSERT INTO NodeHierarchy(PK_NodeID, FK_ParentNodeID, Name)
VALUES
(1, 18, 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'),
(18, NULL, N'United Kingdom'),
(19, 15, N'Upstairs'),
(20, 15, N'Downstairs'),
(21, 16, N'Venue 1'),
(22, 16, N'Venue 2'),
(23, 18, N'England'),
(24, 23, N'Manchester'),
(25, 24, N'Apollo Theatre'),
(26, 18, N'Liverpool'),
(27, 26, N'Cavern Club');
下图是链接问题中列出的 Powershell 脚本 generate-graph.ps1
的输出。如果 Stack Overflow 缩小版看起来很难看,请查看全尺寸图像。
我只想看看圣安德鲁斯的后代和祖先与它有何关系。该图包含大量与这些关系无关的信息,因此更难以阅读。当我将层次结构扩展到覆盖全球城市和场所的数千个节点时,完整的可视化几乎变得毫无用处。
在 Freemind 中,我画了一个我想看到的粗略图表:
我如何仅提取以下数据:与圣安德鲁斯相关,所以我可以将其提供给 GraphViz?
In another question I asked about visualizing hierarchical data stored in a table in an SQL Server database. I found a way to visualize the whole hierarchy using GraphViz, with some plumbing in T-SQL and Powershell.
I want to use a visualization like this to debug an application that uses similar data. Visualizing everything is fine for the small example hierarchy. But in a hierarchy of thousands, this is overwhelming.
When I debug my application, I usually look at only a small set of nodes related to a given node. Currently, the only related nodes that matter to me for a given node are the descendants and the ancestors, as well as the node itself.
So, I want a way to visualize only the nodes in the hierarchy that are the descendants, ancestors, or self of a given node.
The following statements create the example database and table as in the linked question.
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
);
The following statement populates the table with a modified version of the hierarchy of countries, cities, and venues. The United Kingdom is now the root node, and there are more nodes to represent famous English venues.
INSERT INTO NodeHierarchy(PK_NodeID, FK_ParentNodeID, Name)
VALUES
(1, 18, 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'),
(18, NULL, N'United Kingdom'),
(19, 15, N'Upstairs'),
(20, 15, N'Downstairs'),
(21, 16, N'Venue 1'),
(22, 16, N'Venue 2'),
(23, 18, N'England'),
(24, 23, N'Manchester'),
(25, 24, N'Apollo Theatre'),
(26, 18, N'Liverpool'),
(27, 26, N'Cavern Club');
The following image is the output of Powershell script generate-graph.ps1
listed in the linked question. If the Stack Overflow reduced-size version looks ugly, look at the full-size image.
I want to see only how St Andrews' descendants and ancestors relate to it. The diagram contains a lot of information irrelevant to these relationships, and so is harder to read. When I scale my hierarchy up to thousands of nodes covering cities and venues globally, a full visualization becomes almost useless.
In Freemind I drew a crude diagram of what I would like to see instead:
How do I extract only the data that is relevant to St Andrews so I can give it to GraphViz?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
层次结构的自引用表示对于诸如您只想选择一个分支之类的作业来说有点笨拙,因此您需要以未知的次数递归连接到目标表。很有可能,但是每当我在 SQL Server 中使用层次结构时,我都会直接跳到 HierarchyId 。
我不知道我们是否可以同时递归地向上和向下查找树;天真的方法对我来说失败了,所以我将提出一个更简单的替代方案。
您已经拥有当前节点。获取该节点的子节点,然后获取该节点的父节点。将它们联合起来,你就完成了。在 SQL 中执行递归连接的最简单方法是使用 公用表表达式 。
现在,根据您之前的问题,您只需从现有视图中进行选择即可。
A self-referential representation of hierarchy is a bit clunky for jobs like - you want to select only one branch, so you'll need to recursively join onto the target table an unknown number of times. Very possible, but any time I work with hierarchies in SQL Server I jump straight to the HierarchyId.
I don't know if we can recursively look both up and down the tree at the same time; a naive approach fails for me, so I'll present a simpler alternative.
You already have the current node. Get the children of that node, and then get the parents of that node. Union them and you're done. And the easiest way to do recursive joins in SQL is with Common Table Expressions.
Now based on your previous question, you simply need to select from your existing views.
我认为你不介意在这里使用 union,这是一种更简单的方法:
当然,你可以将它放在表函数中以使其通用。
I don't think you heed to use union here, it is a way more simple:
Of course, you can put it in a table function to make it general.