我有一個表Person
有3列:Id, Name, ParentId
其中ParentId
是父行的Id
。SQL Server中的樹結構數據查詢
目前,要顯示整個樹,它必須遍歷所有子元素,直到不再有子元素。這看起來不太有效。
有更好更有效的方法來查詢這些數據嗎?
此外,有沒有更好的方式來表示這個樹像結構在SQL Server數據庫中?我的表/數據庫的另一種設計?
我有一個表Person
有3列:Id, Name, ParentId
其中ParentId
是父行的Id
。SQL Server中的樹結構數據查詢
目前,要顯示整個樹,它必須遍歷所有子元素,直到不再有子元素。這看起來不太有效。
有更好更有效的方法來查詢這些數據嗎?
此外,有沒有更好的方式來表示這個樹像結構在SQL Server數據庫中?我的表/數據庫的另一種設計?
我不認爲設計有任何問題,假設您的親子關係水平有限。下面是一個使用遞歸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;
This might be a useful article.另一種方法是hierarchyid
,但我覺得這對於大多數情況過於複雜。
根據樹的結構,它與主題無關,但不是你的'媽媽'和'爸爸'兄弟姐妹嗎? :)我的意思是每天的生活意義,就像他們有同樣的父親。哦,沒關係 – 2016-06-07 08:58:07
@Varvara是的,當然。 – 2016-06-07 14:17:21
亞倫Bertrands的答案是非常好的一般情況下。如果您只需要一次顯示整棵樹,則可以查詢整個表並在內存中執行樹構建。這可能更加方便和靈活。性能也會稍微好一些(無論如何,整個表都需要下載,C#比SQL Server更快)。
如果你只需要樹的一部分,不建議使用這種方法,因爲你會下載比需要更多的數據。
請參閱http://stackoverflow.com/questions/935098/database-structure-for-tree-data-structure以獲得與答案類似的問題。 – JeremyDWill 2012-04-29 04:32:22
請參閱Bill Karwin的[SQL反模式反擊](http://www.slideshare.net/billkarwin/sql-antipatterns-strike-back)幻燈片組 - 他描述了幾個反模式 - 其中包括您擁有的「樸素樹」併爲其提供可能的解決方案。他還有一本名爲[SQL Antipatterns]的好書(http://pragprog.com/book/bksqla/sql-antipatterns) - 強烈推薦! – 2012-04-29 09:17:01