Hierarchical data is defined as a set of data items that are correlated through hierarchical relationships. In hierarchical relationships, a data item is the parent or child of another item.
Starting in 2008, SQL Server built-in hierarchyid data types make it easier to store and query hierarchical data. Hierarchy is actually a CLR data type.
If you don't know what you are talking about, you can actually do it. Then you can go back and understand it.
Next, create a table and insert some data:
create table RoleMan ( NodeId hierarchyid not null, RoleId int not null, RoleName nvarchar(32) not null, Par_NodeId as NodeId.GetLevel() -- GetLevel()Used to determine the depth (level) of the current level, the top level (root node) is 0, and then add 1 in turn. ) go insert into RoleMan(NodeId,RoleId,RoleName) select '/1/','1','Super Administrator' union select '/1/1/','2','Administrators A' union select '/1/2/','3','Administrators B' union select '/1/1/1/','4','user AA' union select '/1/1/2/','5','user AB' union select '/1/2/1/','6','user BA' union select '/1/2/2/','7','user BB' go select *, NodeId.ToString() NodeId_Path -- because hierarchyid The value of a type is expressed in hexadecimal, which is converted to a string. from RoleMan
Query the ancestor node of the specified node:
-- Query the ancestor node of the specified node declare @NodeId hierarchyid select @NodeId=NodeId from RoleMan where RoleId=5 select *,NodeId.ToString() NodeId_Path from RoleMan where @NodeId.IsDescendantOf(NodeId)=1 -- IsDescendantOf(NodeId),Determines whether the specified node is a descendant of another node, and if so, returns 1
Query the descendant node of the specified node:
-- Query descendant nodes of specified nodes declare @NodeId hierarchyid select @NodeId=NodeId from RoleMan where RoleId=2 select *,NodeId.ToString() NodeId_Path from RoleMan where NodeId.IsDescendantOf(@NodeId)=1 -- IsDescendantOf(NodeId),Determines whether the specified node is a descendant of another node, and if so, returns 1
Returns all nodes at the specified level:
-- Returns all nodes at the specified level declare @NodeId hierarchyid select @NodeId=NodeId from RoleMan where Par_NodeId=1 -- Designated Level 1 select @NodeId select *,NodeId.ToString() NodeId_Path from RoleMan where NodeId.GetAncestor(0)=@NodeId -- GetAncestor(0),Returns the data of the current node at the current level select @NodeId select *,NodeId.ToString() NodeId_Path from RoleMan where NodeId.GetAncestor(1)=@NodeId -- GetAncestor(1),Returns the specified level(@NodeId Data for all nodes at the next level specified as Level 1 -- Number 1 indicates the number of levels to be dropped in the hierarchy.
Insert a new node:
declare @PNodeId hierarchyid declare @NodeId hierarchyid select @PNodeId=NodeId from RoleMan where RoleId=3 -- Get Administrator B Node, which is used to specify a parent for the added node select @NodeId=NodeId from RoleMan where RoleId=7 -- Getting Users BB Node, which specifies which child node is behind the added node insert into RoleMan(NodeId,RoleId,RoleName) values(@PNodeId.GetDescendant(@NodeId, NULL),'8','user BC') --That is, the parent node is 'Administrators B' The following child nodes 'user BB' Add a node later 'user BC' select *, NodeId.ToString() NodeId_Path from RoleMan
Of course, this is when there are children under the parent node, so how should we add them when there are no children under the parent node? Just set the two parameters of GetDescendant(null,null) to null. As follows:
declare @PNodeId hierarchyid select @PNodeId=NodeId from RoleMan where RoleId=8 -- Getting Users BC Node, which is used to specify a parent for the added node insert into RoleMan(NodeId,RoleId,RoleName) values(@PNodeId.GetDescendant(null, NULL),'9','user BCA') -- Adding child nodes to parent nodes without child nodes select *, NodeId.ToString() NodeId_Path from RoleMan
If you need to insert a child between two children below a parent node, you need to specify two parameters of GetDescendant(@Child1,@Child2). As follows:
declare @PNodeId hierarchyid declare @Child1 hierarchyid declare @Child2 hierarchyid select @PNodeId=NodeId from RoleMan where RoleId=2 -- Get Administrator A Node, which is used to specify a parent for the added node select @Child1=NodeId from RoleMan where RoleId=4 -- Get the first child node select @Child2=NodeId from RoleMan where RoleId=5 -- Get the second child node insert into RoleMan(NodeId,RoleId,RoleName) values(@PNodeId.GetDescendant(@Child1, @Child2),'10','user A Queue jumping')-- Administrator at parent node A Subnode users AA And users AB Insert a node user between A Queue jumping select *, NodeId.ToString() NodeId_Path from RoleMan
Change node location:
The GetReparentedValue method should be used to change the location of the node. This method takes two parameters, one is the hierarchyid of the original node and the other is the hierarchyid of the target node.
-- Administrator B Subnode users under nodes BA Move to Administrator A Subnode Users of Nodes AB behind declare @RawNodePath hierarchyid declare @NewNodePath hierarchyid select @RawNodePath=NodeId from RoleMan where RoleId=6 -- Getting node users BA select @NewNodePath=NodeId from RoleMan where RoleId=2 -- Get the Node Administrator A select @NewNodePath=@NewNodePath.GetDescendant(MAX(NodeId), NULL) -- Get the Node Administrator A The largest child node below, the last child node from RoleMan where NodeId.GetAncestor(1)=@NewNodePath -- Get the parent node administrator A All the sublevels below update RoleMan set NodeId=NodeId.GetReparentedValue(@RawNodePath, @NewNodePath) where NodeId.IsDescendantOf(@RawNodePath) = 1 select *, NodeId.ToString() NodeId_Path from RoleMan go
hierarchyid function:
GetLevel(): Used to determine the depth of the current level (level), the top level (root node) is 0, and then add 1 in turn.
ToString(): Because the value of the hierarchyid type is expressed in hexadecimal, ToString() is used to convert the hierarchyid type to a string type.
IsDescendantOf(): Determines whether the specified node is a descendant of another node, and if so, returns 1. A parameter for the specified node.
GetAncestor(n): n=0 returns the data of the current node at the current level. Otherwise, all nodes of the lower N-level at the specified level will be returned.
GetDescendant(null,null): Used to add nodes, this method accepts two parameters, which can be null, the first child node, the second child node. If the first parameter is not empty, it means adding a node after the child node under the specified parent node, and if both parameters are empty, it means adding a node to the node without the child node.
GetReparentedValue(): Used to change the location of a node, this method takes two parameters, one is the hierarchyid of the original node, the other is the hierarchyid of the target node.
GetRoot(): Gets the root of the node.
Parse(): Converts a string to hierarchyid. The format of the string is usually / 1 / like this.
Read(): Read reads the binary representation of SqlHierarchyId from the incoming BinaryReader and sets the SqlHierarchyId object to that value. Read cannot be invoked using Transact-SQL. Please use CAST or CONVERT instead.
Write(): Write writes the binary representation of SqlHierarchyId to the incoming BinaryWriter. Write cannot be invoked by using Transact-SQL. Please use CAST or CONVERT instead.
Hierarchy index strategy:
There are two strategies for indexing hierarchical data: depth first and breadth first.
Depth-first index, the storage location of each row in the subtree is adjacent, in short, it is stored in hierarchy-based value order.
Create a depth-first index:
--Creating Depth First Index create unique index Role_Depth_First on RoleMan(NodeId) go select *,NodeId.ToString() NodeId_Path from RoleMan order by NodeId
The breadth-first index is to store the rows at each level in the hierarchy together, in short, in a hierarchical order.
Create a breadth-first index:
--Create breadth-first index create clustered index Role_Breadth_First on RoleMan(Par_NodeId,NodeId) ; go select *,NodeId.ToString() NodeId_Path from RoleMan order by Par_NodeId,NodeId
Reference resources:
http://blog.csdn.net/zhanghongju/article/details/42584643
https://msdn.microsoft.com/zh-cn/library/bb677173.aspx