(Lviv community of .NET developers)

Hierarchy data on DB layer

October 2, 2007 01:56 by alexk

Hierarchy data on DB layer

Simple ways

ParentId-to-ChildId

  1. define primary key in table
  2. define ParentRef column that has the same data type as primary key has and allowed NULL;
ID Data ParentRef
1 some data NULL
2 node1 1
3 node11 2
4 node2 1

Pluses:

  • easy to implement
  • good structure where data accessed level by level;

Minuses:

  • very complex queries for data extracting; implementation of query "extract node and all it childs" become very complex;

Separator

  1. define separator that can not be used by user
ID Name
1 ArtfulBits
2 ArtfulBits.Test
3 ArtfulBits.Test.Data
4 ArtfulBits.Samples

Pluses:

  • easy to implement
  • easy to extract node and it childs

Minuses:

  • some times is very hard to define seprator
  • growing of Name column value can become a problem if required deep hierarchy;

Combination

  1. define primary key in table
  2. define ParentRef column that has the same data type as primary key has and allowed NULL;
  3. define special index column varchar()
ID Name ParentRef Index
1 node1 NULL NULL
2 node2 1 0001
33 node21 2 0001-0002
4 node211 33 0001-0002-0033
5 node22 2 0001-0002
99 nodeN 33 0001-0002-0033

Pluses:

  • combination of performance and DB space usage
  • easy to extract data in any suitable way

Minuses:

  • required DB trigger on table for update and delete operations

Example

Separator is "/" char. Used 4 (four) chars for index key storage;

CREATE TABLE Articles  
(  
  -- article tree-hierarchy  
  [ArticleID]        [int]             IDENTITY (1, 1)   NOT NULL ,  
  [ArticleParentRef] [int]                               NOT NULL ,  
  [ArticleNodeKey]   [nvarchar](100)                     NULL ,  
  -- article parts  
  [ArtTitle]         [nvarchar](200)                     NULL ,  
  [ArtShortText]     [nvarchar](600)                     NULL ,  
  [ArtText]          [nvarchar](2000)                    NULL ,  
  [ArtTextFormat]    [varchar] (10)                      NULL ,  
  -- article references  
  [ArtUserRef]       [int]                               NULL ,  
  [ArtBlogRef]       [int]                               NULL ,  
  [ArtLanguage]      [varchar] (4)                       NULL ,  
  [ArtTime]          [datetime]                          NULL ,  
    
  CONSTRAINT [PK_Articles] PRIMARY KEY CLUSTERED   
  (  
    [ArticleID] ASC 
  )  
)  
 
GO  
 
CREATE function dbo.fnGetArticleNodeKey( @ID int )  
  returns nvarchar(500)  
as 
begin 
  declare   
    @Key nvarchar(500),   
    @SubKey nvarchar(10),   
    @ParentID int 
 
  select @Key = N'' 
 
  while( @ID is not NULL )  
  begin 
    select @ParentID = ArticleParentRef from Articles where ArticleID = @ID  
 
    set @SubKey = N'/' + right( replicate( '0', 3 ) + cast( @ID as nvarchar( 6 ) ), 4 )  
      
    if( charindex( @SubKey + N'/', @Key ) <> 0 )  
      return NULL 
      
    set @Key = @SubKey + @Key 
    set @ID = @ParentID  
  end 
 
  return @Key 
end 
 
GO  
 
CREATE TRIGGER tg_Articles_NodeKey  
  ON dbo.Articles  
  FOR INSERTUPDATE 
AS BEGIN 
  if TRIGGER_NESTLEVEL( @@PROCID ) = 1  
  begin 
      
    if update( ArticleID ) or update( ArticleParentRef ) or update( ArticleNodeKey )  
    begin 
      
      update Articles set   
        ArticleNodeKey = dbo.fnGetArticleNodeKey( ArticleID )  
      where isNull( ArticleNodeKey, '' ) <> isNull( dbo.fnGetArticleNodeKey( ArticleID ), '' )  
 
      if exists( select * from Articles where ArticleNodeKey is NULL )   
      begin 
        raiserror( 'Recursion in Tasks', 16, 1 )  
        rollback tran  
        return 
      end 
    end 
  end 
END 

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Comments

April 29. 2009 12:16

what a nice post, thanks for informing.

Kampanye Damai Pemilu Indonesia 2009

June 20. 2009 15:13

hello, this is my first time i visit here. I found so many interesting in your blog especially its discussion. keep up the good work.

Sulumits Retsambew

July 15. 2010 04:25

what a nice post, thanks for informing.

vibram fivefingers

Add comment


(Will show your Gravatar icon)