beautylan吧 关注:95贴子:3,251
  • 2回复贴,共1

SQL SERVER 2008 Hierarchyid数据类型

只看楼主收藏回复

SQL SERVER 2008 中的 Hierarchyid数据类型 主要用于存储树结构的数据
SQL SERVER 2008引入了新的hierarchyid数据类型,可以用它来做本地存储并且在树层次结构中管理其位置.只用这个函数能简洁地表示层次结构中的位置.该函数提供的一些内置的函数方法可以操作和遍历层次结构,使得存储和查询分层数据更为容易,而不需要像那样通过CTE递归来获得.
Hierarchyid类型其实是一个CLR自定义数据类型依次打开:数据库->系统数据库->master->可编程性->类型->系统数据类型->CLR数据类型->hierarchyid,可以看到该数据类型.
于hierarchyid有关的一些函数主要有:
GetAncestor :取得某一个级别的祖先
GetDescendant :取得某一个级别的子代
GetLevel :取得级别
GetRoot :取得根
IsDescendantOf :判断某个节点是否为某个节点的子代
Parse :将字符串转换为hierarchyid。该字符串的格式通常都是/1/这样的
Read :Read 从传入的BinaryReader 读取SqlHierarchyId 的二进制表示形式,并将SqlHierarchyId 对象设置为该值。不能使用Transact-SQL 调用Read。请改为使用CAST 或CONVERT。
GetReparentedValue :可以用来移动节点(或者子树)
ToString :将hierarchyid转换为字符串,与parse正好相反
Write : 将SqlHierarchyId 的二进制表示形式写出到传入的BinaryWriter 中。无法通过使用Transact-SQL 来调用Write。请改为使用CAST 或CONVERT。
用于对分层数据进行索引的策略有两种:
深度优先
深度优先搜索与前序、中序、后序遍历。
深度优先搜索是图论中的经典算法,假设初始状态是图中所有顶点都未被访问,则深度优先搜索方法的步骤是:
1)选取图中某一顶点Vi为出发点,访问并标记该顶点;2)以Vi为当前顶点,依次搜索Vi的每个邻接点Vj,若Vj未被访问过,则访问和标记邻接点Vj,若Vj已被访问过,则搜索Vi的下一个邻接点;3)以Vj为当前顶点,重复步骤2),直到图中和Vi有路径相通的顶点都被访问为止;4)若图中尚有顶点未被访问过(非连通的情况下),则可任取图中的一个未被访问的顶点作为出发点,重复上述过程,直至图中所有顶点都被访问。
由算法步骤很容易知道可以用递归实现深度优先搜索,栈和递归是可以相互转换的,所以其非递归算法可以用栈实现。
树的图的特例,树的三种遍历算法前序、中序、后序遍历都是深度优先搜索的特例。前序是深度优先很好理解,就是把根节点选为第一个节点,第一次入这个节点就访问。中序可以看做把最左的点选为第一个节点。后序遍历,也是把根节点选为第一个节点,但是是出节点时访问。


IP属地:上海1楼2017-03-21 14:38回复
    广度优先搜索算法(
    Breadth First Search
    ),又叫宽度优先搜索,或横向优先搜索。


    IP属地:上海2楼2017-03-21 15:35
    回复
      例如下面的例子是一个职员表,数据有如下关系:
      Scott
      |
      Mark <- > Ravi
      | |
      Ben<-> Laura Vijay <-> Frank <-> James
      Use AdventureWorksLT
      Go
      --Scheme Creation
      Create Schema HumanResources
      Go
      --Table Creation
      CREATE TABLE HumanResources.EmployeeDemo
      (
      OrgNode HIERARCHYID,
      EmployeeID INT,
      LoginID VARCHAR(100),
      Title VARCHAR(200),
      HireDate DATETIME
      )
      Go
      --Index Creation
      CREATE UNIQUE CLUSTERED INDEX idxEmployeeDemo
      ON HumanResources.EmployeeDemo (OrgNode,EmployeeID)
      下面插入一些数据
      SERT HumanResources.EmployeeDemo (OrgNode, EmployeeID, LoginID, Title, HireDate)
      LUES (hierarchyid::GetRoot(), 1,'adventure-works\scott', 'CEO', '3/11/05') ;
      CLARE @Manager hierarchyid
      LECT @Manager = hierarchyid::GetRoot() FROM HumanResources.EmployeeDemo;
      SERT HumanResources.EmployeeDemo (OrgNode, EmployeeID, LoginID, Title, HireDate)
      LUES (@Manager.GetDescendant(NULL,NULL), 2, 'adventure-works\Mark', 'CTO', '4/05/07')
      CLARE @Manager hierarchyid
      CLARE @FirstChild hierarchyid
      LECT @Manager = hierarchyid::GetRoot() FROM HumanResources.EmployeeDemo;
      lect @FirstChild = @Manager.GetDescendant(NULL,NULL)
      SERT HumanResources.EmployeeDemo (OrgNode, EmployeeID, LoginID, Title, HireDate)
      LUES (@Manager.GetDescendant(@FirstChild,NULL), 3, 'adventure-works\ravi', 'Director Marketing', '4/08/07')
      Insert the First Descendant of a Child Node
      CLARE @Manager hierarchyid
      LECT @Manager = CAST('/1/' AS hierarchyid)
      SERT HumanResources.EmployeeDemo (OrgNode, EmployeeID, LoginID, Title, HireDate)
      LUES (@Manager.GetDescendant(NULL, NULL),45, 'adventure-works\Ben','Application Developer', '6/11/07') ;
      Insert the Second Descendant of a Child Node
      CLARE @Manager hierarchyid
      CLARE @FirstChild hierarchyid
      LECT @Manager = CAST('/1/' AS hierarchyid)
      LECT @FirstChild = @Manager.GetDescendant(NULL,NULL)
      SERT HumanResources.EmployeeDemo (OrgNode, EmployeeID, LoginID, Title, HireDate)
      LUES (@Manager.GetDescendant(@FirstChild, NULL),55, 'adventure-works\Laura','Trainee Developer', '6/11/07') ;
      Insert the first node who is the Descendant of Director Marketing
      CLARE @Manager hierarchyid
      CLARE @FirstChild hierarchyid
      LECT @Manager = CAST('/2/' AS hierarchyid)
      SERT HumanResources.EmployeeDemo (OrgNode, EmployeeID, LoginID, Title, HireDate)
      LUES (@Manager.GetDescendant(NULL, NULL),551, 'adventure-works\frank','Trainee Sales Exec.', '12/11/07') ;
      Insert the second node who is the Descendant of Director Marketing
      CLARE @Manager hierarchyid
      CLARE @FirstChild hierarchyid
      LECT @Manager = CAST('/2/' AS hierarchyid)
      LECT @FirstChild = @Manager.GetDescendant(NULL,NULL)
      SERT HumanResources.EmployeeDemo (OrgNode, EmployeeID, LoginID, Title, HireDate)
      LUES (@Manager.GetDescendant(@FirstChild, NULL),531, 'adventure-works\vijay','Manager Industrial Sales', '12/09/06') ;
      Insert the third node who is the Descendant of Director Marketing
      in between 2 existing descendants
      CLARE @Manager hierarchyid
      CLARE @FirstChild hierarchyid
      CLARE @SecondChild hierarchyid
      LECT @Manager = CAST('/2/' AS hierarchyid)
      LECT @FirstChild = @Manager.GetDescendant(NULL,NULL)
      LECT @SecondChild = @Manager.GetDescendant(@FirstChild,NULL)
      SERT HumanResources.EmployeeDemo (OrgNode, EmployeeID, LoginID, Title, HireDate)
      LUES (@Manager.GetDescendant(@FirstChild, @SecondChild),543, 'adventure-works\james','Manager Consumer Sales', '12/04/06') ;
      Hierarchyid字段类型提供了一系列相关查询函数,可以方便的查询父子关系数据。下面我们查询下数据DECLARE @TID hierarchyid
      SELECT @TID=OrgNode FROM HumanResources.EmployeeDemo WHERE title='cto'
      SELECT *, OrgNode.GetLevel() as 层次,OrgNode.ToString() as 路径 FROM HumanResources.EmployeeDemo WHERE @TID.IsDescendantOf(OrgNode)=1
      SELECT *, OrgNode.GetLevel() as 层次,OrgNode.ToString() as 路径 FROM HumanResources.EmployeeDemo WHERE OrgNode.IsDescendantOf(@TID)=1


      IP属地:上海3楼2017-03-21 15:45
      回复