Отображение дерева пути записи в SQL Server 2005 - PullRequest
0 голосов
/ 14 февраля 2010

Пример моей древовидной таблицы: ([id] - это личность)

[id], [parent_id], [path]

1, NULL, 1

2, 1, 1-2

3, 1, 1-3

4, 3, 1-3-4

Моя цель состоит в том, чтобы быстро запросить несколько строк в этой таблице и просмотреть полный путь узла от его корня до его старших элементов и до самого себя. Главный вопрос заключается в том, должен ли я сгенерировать этот путь для вставок и сохранить его в отдельном столбце или сгенерировать этот путь в запросе для экономии места на диске? Я думаю, это зависит от того, будет ли эта таблица тяжелой или тяжелой.

Я обдумывал несколько подходов к использованию характеристики «пути» в этих отношениях родитель / ребенок, и я просто не могу остановиться на одном. Этот «путь» просто для демонстрации и не служит абсолютно никакой другой цели. Вот что я сделал для реализации этого «пути».

  1. ПОСЛЕ INSERT TRIGGER - требуется передать NULL-путь к вставке и обновить путь для записи с идентификатором вставленных строк
  2. INSTEAD OF INSERT TRIGGER - не требует, чтобы вставка передавала путь NULL, но требует триггера для вставки с путем NULL и обновления пути для записи в SCOPE_IDENTITY ()
  3. ХРАНЕННАЯ ПРОЦЕДУРА - требуется, чтобы все вставки в эту таблицу выполнялись с помощью хранимой процедуры, реализующей логику триггера
  4. VIEW - требуется построить путь в представлении

1 и 2 кажутся раздражающими, если одновременно вводится большое количество данных.

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

1, 2 и 3 требуют ведения столбца пути в таблице.

4 снимает все ограничения, описанные выше, но требует, чтобы представление выполняло логику пути, и требует использования представления для отображения пути.

Я успешно реализовал все вышеперечисленные подходы и в основном ищу несколько советов. Я далеко от цели или приемлемо ли что-либо из вышеперечисленного? У каждого есть свои преимущества и недостатки.

Ответы [ 3 ]

1 голос
/ 14 февраля 2010

«Это зависит», безусловно, относится к этому. Есть так много возможностей, просто невозможно назвать The Best One. Вот несколько идей.

Как часто добавляются новые данные? Можно ли изменить данные (или удалить элементы) так, чтобы изменилась иерархическая «цепочка»? Сколько данных / насколько велика таблица? Как вы будете использовать данные? Насколько важно быть современным? Все это приводит к различным возможным реализациям, основанным на требованиях к производительности.

У нас есть аналогичная настройка в хранилище данных. Данные вводятся в контролируемых пакетах ETL, поэтому мы можем позволить себе передать их через хранимую процедуру, чтобы правильно определить и загрузить столбец «пути», и тогда мы никогда не будем беспокоиться об этом снова.

За исключением веских причин, я бы пошел с реализацией хранимой процедуры, хотя бы потому, что код может быть немного сложнее. Если вы не можете контролировать людей, вставляющих / обновляющих / удаляющих [ я изначально написал «monkeying» ] с данными вне хранимой процедуры, то я думаю, у вас есть проблемы с безопасностью. Если данные могут быть неточными или устаревшими в течение коротких периодов времени, у вас может быть запланированная подпрограмма, которая регулярно проверяет и повторно калибрует записи (либо новые неустановленные элементы, либо перепроверяет все для изменений.)

1 голос
/ 14 февраля 2010

Вы можете использовать рекурсивное CTE (Common Table Expression) - но не спрашивайте меня, насколько хорошо оно будет работать :-)

Что-то вроде:

WITH RecursiveCTE AS
(
    SELECT ID, ParentID, CAST(ID AS VARCHAR(100)) AS 'Path'
    FROM dbo.YourTableName
    WHERE ParentID IS NULL

    UNION ALL

    SELECT t.ID, t.ParentID, CAST(cte.Path + '-' + CAST(t.ID AS VARCHAR(3)) AS VARCHAR(100)) AS 'Path'
    FROM dbo.YourTableName t
    INNER JOIN RecursiveCTE cte ON t.ParentID = cte.ID
)
SELECT * FROM RecursiveCTE

В моем случае работает нормально, никакого дополнительного обслуживания не требуется - но опять же: я не могу предсказать, как производительность будет - попробуйте!

0 голосов
/ 14 февраля 2010

Если это только для целей отображения, используйте метод 5. Не беспокойтесь об этом!

Есть ли у вас слои пользовательского интерфейса, если и когда потребуется

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...