Вопрос по sql-server-2008, sql-server, database – Запрос данных древовидной структуры в SQL Server

11

У меня есть столPerson это имеет 3 столбца:Id, Name, ParentId гдеParentId этоId родительского ряда.

В настоящее время, чтобы отобразить все дерево, ему пришлось бы перебирать все дочерние элементы, пока не останется никаких дочерних элементов. Это не кажется слишком эффективным.

Есть ли лучший и более эффективный способ запроса этих данных?

Кроме того, есть ли лучший способ представить эту древовидную структуру в базе данных SQL Server? Альтернативный дизайн для моей таблицы / базы данных?

Увидетьstackoverflow.com/questions/935098/… на аналогичный вопрос с ответами. JeremyDWill
Смотри Билла КарвинаSQL Antipatterns strike back слайд-колода - он описывает несколько антипаттернов - среди них «наивное дерево» что у вас есть - и предлагает возможные решения для этого. У него также есть замечательная книга с тем же именемSQL Antipatterns - настоятельно рекомендуется! marc_s

Ваш Ответ

2   ответа
4

Ответ Аарона Бертранса очень хорош для общего случая. Если вам когда-либо нужно отобразить все дерево сразу, вы можете просто запросить всю таблицу и выполнить построение дерева в памяти. Это, вероятно, будет более удобным и гибким. Производительность также будет немного лучше (вся таблица должна быть загружена в любом случае, и C # быстрее для таких вычислений, чем SQL Server).

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

21

Я не думаю, что с дизайном что-то не так, если предположить, что у вас ограниченный уровень родительско-дочерних отношений. Вот краткий пример получения отношения с использованием рекурсивного CTE:

USE tempdb;
GO

CREATE TABLE dbo.tree
(
    ID INT PRIMARY KEY,
    name VARCHAR(32),
    ParentID INT FOREIGN KEY REFERENCES dbo.tree(ID)
);

INSERT dbo.tree SELECT 1, 'grandpa', NULL
UNION ALL SELECT 2, 'dad', 1
UNION ALL SELECT 3, 'me', 2
UNION ALL SELECT 4, 'mom', 1
UNION ALL SELECT 5, 'grandma', NULL;

;WITH x AS
(
    -- anchor:
    SELECT ID, name, ParentID, [level] = 0
    FROM dbo.tree WHERE ParentID IS NULL
    UNION ALL
    -- recursive:
    SELECT t.ID, t.name, t.ParentID, [level] = x.[level] + 1
    FROM x INNER JOIN dbo.tree AS t
    ON t.ParentID = x.ID
)
SELECT ID, name, ParentID, [level] FROM x
ORDER BY [level]
OPTION (MAXRECURSION 32);
GO

Не забудьте очистить:

DROP TABLE dbo.tree;

Это может быть полезной статьей. Альтернативаhierarchyid но я нахожу это слишком сложным для большинства сценариев.

Это не имеет отношения к теме, но не относится к вашей маме. и "папа"; братья и сестры, в соответствии со структурой вашего дерева? :) Я имею в виду ежедневный живой смысл, как будто у них один и тот же отец. О, неважно
@ Варвара Да, конечно.

Похожие вопросы