Каковы различия в этих примерах таблицы замыкания SQL?

У меня возникли некоторые трудности, связанные с обработкой таблиц закрытия SQL, и я хотел бы получить некоторую помощь в понимании некоторых примеров, которые я нашел.

Допустим, у меня есть стол под названием sample_items со следующими иерархическими данными:

id   name                   parent_id
1    'Root level item #1'   0
2    'Child of ID 1'        1
3    'Child of ID 2'        2
4    'Root level item #2'   0

Древовидная структура должна быть такой:

id
| - 1 
|   | - 2
|       | - 3
| - 4

Для простоты запросов к деревьям (например, для нахождения всех потомков определенного идентификатора) у меня есть таблица с именем sample_items_closure используя метод, описанный Биллом Карвином в этом превосходном посте SO. Я также использую дополнительный path_length столбец для запроса ближайшего ребенка или родителя, когда это необходимо. Если я правильно понимаю этот метод, мои данные таблицы закрытия будут выглядеть так:

ancestor_id   descendant_id   path_length
1             1               0
2             2               0
1             2               1
3             3               0
2             3               1
1             3               2
4             4               0

Каждый ряд в sample_items теперь есть запись в sample_items_closure стол как для себя, так и для всех его предков. Пока все имеет смысл.

Однако, изучая другие примеры таблиц замыканий, я натолкнулся на один, который добавляет дополнительного предка для каждой строки, которая связана с корневым уровнем (ancestor_id 0) и имеет длину пути 0. Используя те же данные, которые были у меня выше, это то, что таблица закрытия будет выглядеть так:

ancestor_id   descendant_id   path_length
1             1               0
0             1               0
2             2               0
1             2               1
0             2               0
3             3               0
2             3               1
1             3               2
0             3               0
4             4               0
0             4               0

Чтобы лучше понять контекст, вот запрос на выборку, используемый на этом сайте, измененный в соответствии с моими примерами:

SELECT `id`,`parent_id` FROM `sample_items` `items`
  JOIN `sample_items_closure` `closure`
  ON `items`.`id` = `closure`.`descendant_id`
  WHERE `closure`.`ancestor_id` = 2

У меня есть два вопроса, связанных с этим методом:

Вопрос 1:

Зачем нужна дополнительная строка, связывающая каждого потомка с корневым уровнем (id 0)?

Вопрос 2:

Почему path_length для этих записей будет 0, а не path_length предыдущего предка +1? Например:

ancestor_id   descendant_id   path_length
1             1               0
0             1               1
2             2               0
1             2               1
0             2               2
3             3               0
2             3               1
1             3               2
0             3               3
4             4               0
0             4               1

Бонусный вопрос: почему некоторые примеры все еще включают в себя список смежности (parent_id колонка для sample_items в моем примере) когда полная структура дерева уже выражена в таблице замыканий?

1 ответ

Вы могли бы использовать CTE. Они созданы именно для этих вариантов использования и имеют много замечательных примеров, которые близки к вашему случаю.

Другие вопросы по тегам