2013-05-02 43 views
1

我們使用具有名爲docid的列和名爲parentid的列的表來存儲Oracle數據庫中文檔之間的關係。如果我有一個與子文檔child1_1和child1_2相關的文檔doc1,它們將由Documents表中的以下記錄表示。在SQL中實現排序鍵

docid parentid 
1000 null record for doc1 
1001 1000 "  " child1_1 
1002 1000 "  " child1_2 

文檔表可以有幾百萬行的,所以要確保所有相關文件都集合在我們的UI,我們使用sortedfamily命名索引VARCHAR列的文件表預先排序,並串聯填充它的相關文件的docids。如果不使用sortedfamily列,則在查詢時對記錄進行排序太慢。上面顯示的記錄成爲。

docid parentid sortedfamily 
1000 null  1000   record for doc1 
1001 1000  1000_1001  "  " child1_1 
1002 1000  1000_1002  "  " child1_2 

這使我們可以在查詢中添加'ordered by sortedfamily',返回的記錄將總是按相關文檔排序。我上面概述的工作非常好,但它有一些與文檔系列分層深度有關的限制,並且感覺奇怪的拼接整數來排序記錄。有沒有辦法做到以上只使用整數?

在此先感謝。

更新:我上面的示例不夠詳細。孩子們自己也可能有相關的文件。如果child1_1擁有相關文檔,那麼sortedfamily的結果值可能爲「1000_1001_2000」。

+0

如果先按parentid排序,再按docid排序會怎樣。 Order by COALESCE(parentid,docid),docid – Gentlezerg 2013-05-02 03:13:18

+0

Documents表可以包含數百萬行,並且我們發現如果沒有包含排序鍵的列,則表現是不合格的。 – user481779 2013-05-02 03:42:54

回答

5

Oracle對分層查詢有很好的支持。您可以獲取文檔層次結構,而無需使用sortedfamily列。這裏的查詢:

SELECT docid, PRIOR docid AS "Parent" 
FROM Documents 
START WITH parentid IS NULL 
CONNECT BY parentid = PRIOR docid 
ORDER SIBLINGS BY docid 

我們解釋:

SELECT docid, PRIOR docid AS "Parent" 

這得到的文件,並通過「回頭看」與PRIOR運營其在同一行父。

START WITH parentid IS NULL 

這定義了層次結構的根。每行有空值parentid被視爲分支的根。

CONNECT BY parentid = PRIOR docid 

這表示,當前行的「父」是由孩子起來parentid連接於母公司docid

ORDER SIBLINGS BY docid 

這種排序方式是沿着整個層次而不是單個值。這很難解釋,但它的工作原理。

關於Oracle分層查詢的最好的事情是他們會查詢整個分支,所以如果你有一個有孩子的孩子的文檔(有一個孩子,那麼......),Oracle會處理它。它也將處理每個家長的多個孩子。

有一個SQL Fiddle here與您的數據加上一些額外的文件。

小提琴還包含一個使用SYS_CONNECT_BY_PATH函數顯示整個「根到分支」關係的列。 SYS_CONNECT_BY_PATHsortedfamily列的功能相同,但它是動態執行的,無需維護該列。這也是一種很好的方式來可視化層次結構的每個分支。

附錄

注意,上面的查詢將返回分行文件。如果你是爲docid = 1000一個單一的文件,例如在剛興趣的話,更換START WITH parentid IS NULL本:

START WITH docid = 1000 

這會給你docid 1000整個分支如果您有docid索引這將是非常快。

+0

感謝Ed提供的詳細解決方案。你可以看看我對OP做出的修改,並指出這是否會改變你的解決方案?我們的文檔表通常有數千萬行。您的解決方案是否可行? – user481779 2013-05-02 14:28:33

+0

如果兒童文件有孩子,該解決方案將起作用。 Oracle會找到整個分支。要看到它的行動,去小提琴(有一個鏈接到上面),並改變'START WITH parentid IS NULL'到'開始與docid = 4000'。小提琴數據設置'docid 4000'具有多層兒童。 – 2013-05-02 14:34:15

+0

非常感謝。有關這種技術在數千萬行的情況下是否可行的評論? – user481779 2013-05-02 14:52:07