Поиск иерархии по «самому правому» узлу - PullRequest
0 голосов
/ 03 мая 2018

Я немного новичок в типе данных 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 технически избыточен.

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, и мне нужно найти строку справа узел. * * 1 021

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 голосов
/ 03 мая 2018

Вы можете создать вычисляемое и постоянное поле для своего идентификатора:

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

...