我对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, '/')
任何人都知道这样做的好方法吗?
答案 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