按 "right-most" 个节点搜索 hierarchyid
Search hierarchyid by "right-most" node
我对 hierarchyid
数据类型有些陌生。我正在尝试表示给定层次结构中的实体。为了争论,假设他们是经典 "boss of" 层次结构中的人,但它可以是任何东西。
最初,我想出了一个结构,其中有一列用于实体的 id
以及它在层次结构中的位置。所以 Id
列本质上是层次结构中的 "right-most" 节点。
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
列中的值与层次结构中的 "right-most" 节点相同,Id
列在技术上就是多余的.
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, '/')
有人知道这样做的好方法吗?
您可以为您的 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
我对 hierarchyid
数据类型有些陌生。我正在尝试表示给定层次结构中的实体。为了争论,假设他们是经典 "boss of" 层次结构中的人,但它可以是任何东西。
最初,我想出了一个结构,其中有一列用于实体的 id
以及它在层次结构中的位置。所以 Id
列本质上是层次结构中的 "right-most" 节点。
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
列中的值与层次结构中的 "right-most" 节点相同,Id
列在技术上就是多余的.
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, '/')
有人知道这样做的好方法吗?
您可以为您的 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