通过“最右侧”节点搜索hierarchyid

时间:2018-05-02 21:07:12

标签: sql-server hierarchyid

我对hierarchyid数据类型有些新意。我试图在给定的层次结构中表示实体。为了论证,让我们说他们是经典的“老板”层级中的人,但它可以是任何东西。

最初,我想出了一个结构,它有一个实体的id列,它位于层次结构中。因此Id列本质上是层次结构中的“最右侧”节点。

create table #WithId
(
    Id int primary key clustered,
    hPath hierarchyid,
    sPath as hPath.ToString()
)

insert into #WithId (Id, hPath)
values
    (1, '/1/'), (2, '/2/'), (3, '/1/3/'), (4, '/1/4/'), 
    (5, '/2/5/'), (6, '/1/6/'), (7, '/2/7/'), (8, '/2/7/8/')

虽然我发现,只要Id列中的值与层次结构中的“最右侧”节点相同,Id列在技术上就是多余的。 / p>

create table #WithoutId
(
    hPath hierarchyid primary key clustered,
    sPath as hPath.ToString()
)

insert into #WithoutId (hPath)
select hPath
from #WithId

但是,我仍然需要一种快速查找实体并找到其上游层次结构的方法。使用专用的id列,只需搜索该列

即可
declare @SomeId int = 8

-- Easy
select hPath, sPath
from #WithId
where Id = @SomeId

但是,如果我没有有一个专用的Id列,我无法找到一个好的方法,我需要通过最右边的节点。

declare @AnotherId int = 8

-- This is totally hack, but functionally what I'm looking for
select hPath, sPath
from #WithoutId
where sPath like concat('%/', @AnotherId, '/')

任何人都知道这样做的好方法吗?

1 个答案:

答案 0 :(得分:1)

您可以为您的Id创建计算和持久字段:

create table #WithId
(
    Hid     hierarchyid,
    HidPath as Hid.ToString(),
    Id      as cast(replace(replace(Hid.ToString(), Hid.GetAncestor(1).ToString(), ''), '/', '') as int) persisted,

    primary key (Id)
)

因此,您可以规范化数据结构,并且仍然具有良好的搜索速度。

但对我来说,hierarchyid类型不仅可用于显示层次结构中的位置,还可以定义其子项中项目的顺序。而使用hierarchyid类型只是为了身份是浪费宝贵的资源,我想:)

请阅读我的文章:

https://www.codeproject.com/Articles/1192607/Combination-of-Id-ParentId-and-HierarchyId