2011-08-22 8 views
9

Non ho trovato alcun esempio specifico ma sono interessato a rappresentare un'intera struttura di directory con aggiornamenti, ecc. Utilizzando il tipo di dati hierarchyid. Questo è un caso di uso comune citato per la gerarchia, ma non riesco a trovare alcun articolo che costruisca un simile esempio.Rappresenta il file system nel DB (utilizzando hierarchyid in SQL Server 2008)

Voglio solo per rappresentare una intera struttura di directory come ad esempio:

/dir1 
/file1 
/dir2 
/dir2/dir3 
/dir2/dir3/file2 

** Non sto cercando di sincronizzare questo con un sistema di file sul disco. È puramente rappresentato attraverso il database. **

+2

Come si aspetta di mantenere la struttura della tabella in sincronia con il file sistema? Se aggiungo un file in/dir2, quanto velocemente dovrebbe sapere la tabella? Immediatamente, qualche ritardo, mai? Non avrebbe più senso leggere semplicemente la struttura delle directory in fase di esecuzione? Non avrebbe davvero bisogno di gerarchia per questo. –

+0

Grazie, non sto cercando di mantenere il DB in sincronia con il file system. Fondamentalmente agirà come un proprio file system (i nodi dei file punteranno a file su disco ma non ci sarà una struttura di directory). Tutto ciò di cui ho davvero bisogno di aiuto è solo questa parte. Grazie. – user8790899800

+0

Perché il commento di @Aaron Bertrand viene messo in aumento quando non è realmente pertinente? Sembra strano. – user8790899800

risposta

7

Ecco un esempio di rappresentare un sistema di file attraverso hierarchyid:

/* 
Setup: 
- Create the table to hold the files 
- nodeDepth is identifier of the depth for readability 
- fullpath is the full path of the file or directory 
- nodePath is the HierarchyID 
- nodePath identifies the row within the tree 
*/ 

DECLARE @t TABLE (
    nodeID INT NOT NULL IDENTITY(1,1) PRIMARY KEY, 
    nodeDepth VARCHAR(10) NOT NULL, 
    fullPath VARCHAR(20) NOT NULL, 
    nodePath HIERARCHYID NOT NULL 
) 

dati di carico:

/* 
Load the nodePath value with the Parse command: 
- The root node has a single/
- Every nodePath must begin and end with/
- /1/2/ the second item on level 2 
*/ 

INSERT @t (fullPath, nodeDepth, nodePath) VALUES 
('/','1',HIERARCHYID::Parse('/')), 
('/dir1','1.1',HIERARCHYID::Parse('/1/1/')), 
('/file1','1.2',HIERARCHYID::Parse('/1/2/')), 
('/dir2','1.3',HIERARCHYID::Parse('/1/3/')), 
('/dir2/dir3','1.3.1',HIERARCHYID::Parse('/1/3/1/')), 
('/dir2/dir3/file2','1.3.1.1',HIERARCHYID::Parse('/1/3/1/1/')) 

Mostra i percorsi:

SELECT * 
FROM @t 

nodeID  nodeDepth fullPath    nodePath 
----------- ---------- -------------------- -------- 
1   1  /     0x 
2   1.1  /dir1    0x5AC0 
3   1.2  /file1    0x5B40 
4   1.3  /dir2    0x5BC0 
5   1.3.1  /dir2/dir3   0x5BD6 
6   1.3.1.1 /dir2/dir3/file2  0x5BD6B0 

Get antenati di file2 (Sali):

SELECT * 
FROM @t 
WHERE nodePath = 
    (SELECT nodePath.GetAncestor(1) 
    FROM @t 
    WHERE fullPath = '/dir2/dir3/file2') 

nodeID  nodeDepth fullPath    nodePath 
----------- ---------- -------------------- --------- 
5   1.3.1  /dir2/dir3   0x5BD6 

ottenere tutti descentants di dir2:

SELECT * 
FROM @t 
WHERE nodePath.IsDescendantOf(
    (SELECT nodePath 
    FROM @t 
    WHERE fullPath = '/dir2')) = 1 
AND fullPath <> '/dir2' /* Parent is considered its own descendant */ 

nodeID  nodeDepth fullPath    nodePath 
----------- ---------- -------------------- -------- 
5   1.3.1  /dir2/dir3   0x5BD6 
6   1.3.1.1 /dir2/dir3/file2  0x5BD6B0 

ottenere il percorso principale:

SELECT * 
FROM @t 
WHERE nodePath = HIERARCHYID::GetRoot() 

nodeID  nodeDepth fullPath    nodePath 
----------- ---------- -------------------- -------- 
1   1  /     0x 

Prendi il livello l di file2:

SELECT nodePath.GetLevel() AS level 
FROM @t 
WHERE fullPath = '/dir2/dir3/file2' 

level 
------ 
4 

Riferimenti: