hierarchyid 和 父\子

本文对比了SQL Server中父/子结构与hierarchyid数据类型在处理层次结构数据时的性能差异。hierarchyid在子树查询速度上有优势,但在非叶节点移动时较慢。父/子结构适合键大小敏感、查询不跨越层次结构不同部分及非叶子树移动频繁的情况。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

父/子

使用父/子方法时,每一行都包含对父级的引用。下表定义了一个用于在父/子关系中包含父行和子行的典型表:

复制代码
USE AdventureWorks2008R2 ;
GO

CREATE TABLE ParentChildOrg
   (
    BusinessEntityID int PRIMARY KEY,
    ManagerId int REFERENCES ParentChildOrg(BusinessEntityID),
    EmployeeName nvarchar(50) 
   ) ;
GO

针对一些常见操作比较父/子与 hierarchyid

  • 使用 hierarchyid 进行子树查询时速度明显加快。

  • 使用 hierarchyid 进行直接后代查询时速度稍慢。

  • 使用 hierarchyid 移动非叶节点时速度明显减慢。使用 hierarchyid 插入非叶节点和插入或移动叶节点具有相同的复杂度。

当存在以下情况时,使用父/子可能更好:

  • 键的大小非常重要。在节点数相同的情况下,hierarchyid 值等于或大于整型系列(smallintintbigint)的值。这只是在很少情况下使用父/子的一个原因,因为 hierarchyid 在 I/O 局部实用性和 CPU 复杂性方面明显优于使用父/子结构时所需的公用表表达式。

  • 很少跨层次结构的不同部分执行查询。也就是说,是否通常仅对层次结构中的单个点进行查询。在这些情况下,存储在一起并不重要。例如,如果组织表仅用于为各个雇员运行工资单,则使用父/子更好。

  • 非叶子树移动频繁并且性能非常重要。在父/子表示形式中,更改层次结构中行的位置将影响单个行。使用 hierarchyid 时,更改行的位置将影响 n 行,其中 n 是要移动的子树中的节点数。

    如果这种非叶子树移动频繁并且性能非常重要,但多数移动操作都是在比较明确的层次结构级别上进行的,请考虑将较高和较低的级别拆分成两个层次结构。这样,所有的移动操作都是移到较高层次结构的叶级。例如,假设有一个由服务承载的网站的层次结构。各网站包含许多以分层方式排列的页面。承载的网站可能移动到网站层次结构中的其他位置,但是从属的页面很少会重新排列。这种情况可表示如下:

    复制代码
    CREATE TABLE HostedSites 
       (
        SiteId hierarchyid, PageId hierarchyid
       ) ;
    GO
posted on 2011-05-12 14:27  Fanr_Zh 阅读( ...) 评论( ...) 编辑 收藏

转载于:https://www.cnblogs.com/Amaranthus/archive/2011/05/12/2044337.html

### SQL Server 中 `hierarchyid` 数据类型的使用 #### 创建带有 `hierarchyid` 列的表 为了展示如何在 SQL Server 中使用 `hierarchyid` 数据类型,可以通过创建一个简单的员工层次结构表来说明。此表将记录每位员工及其上的关系。 ```sql CREATE TABLE Employees ( EmployeeID INT PRIMARY KEY IDENTITY, ParentEmployeeID HIERARCHYID, LevelInOrg AS ParentEmployeeID.GetLevel(), Name NVARCHAR(100), Position NVARCHAR(50) ); ``` 在此示例中,`ParentEmployeeID` 是用来表示组织内上下关系的关键字段[^1]。 #### 插入数据到含有 `hierarchyid` 的表 向上述表格插入一些初始数据: ```sql INSERT INTO Employees (ParentEmployeeID, Name, Position) VALUES (NULL, 'CEO', 'Chief Executive Officer'), ('/1/', 'CTO', 'Chief Technology Officer'), ('/2/', 'CFO', 'Chief Financial Officer'); ``` 这里 `/1/`, `/2/` 表达的是根节点下的第一个第二个节点的位置路径。 #### 查询并显示层信息 利用 `ToString()` 方法可以方便地查看 `hierarchyid` 实际上是如何表达树状结构的信息;而 `GetAncestor()`, `IsDescendantOf()` 等函数则可用于执行更复杂的查询操作。 ```sql SELECT e.EmployeeID, e.Name, e.Position, e.ParentEmployeeID.ToString() as PathString FROM Employees e; ``` 这会返回每一行对应的完整路径字符串形式,便于理解各个成员之间的相对位置关系。 #### 更新现有记录中的 `hierarchyid` 当需要调整某位员工在其组织架构图里的具体位置时,则可通过修改其 `hierarchyid` 来实现移动效果。比如让一位新加入的技术总监成为 CTO 下属的第一名直接汇报对象: ```sql DECLARE @NewPosition HIERARCHYID; SET @NewPosition = '/1/1/'; UPDATE Employees SET ParentEmployeeID=@NewPosition WHERE Name='技术总监'; ``` 这段脚本先声明了一个新的 `hierarchyid` 变量代表目标位置,再将其赋给特定人员完成职位变动处理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值