【问题标题】:Some questions about HierarchyId (SQL Server 2008)关于 HierarchyId (SQL Server 2008) 的一些问题
【发布时间】:2010-12-27 05:28:45
【问题描述】:

我是 SQL Server 2008 的新手,刚刚被介绍给 HierarchyId。

我正在向SQL Server 2008 - HIERARCHYID - PART I 学习。所以基本上我是逐行阅读文章,在 SSMS 中练习时,我发现每个 ChildId 都会生成一些十六进制值,例如 0x,0x58,0x5AC0 等。

我的问题是

  1. 这些十六进制值是什么?
  2. 为什么会生成这些以及它们的用途是什么?我的意思是我可以在哪里使用这些六进制值?
  3. 我们是否可以控制这些六进制值?我的意思是我们可以更新等。
  4. 如何通过查看这些 hexa 值来确定层次结构。我的意思是如何确定哪个是父级,哪个是子级?

【问题讨论】:

    标签: sql-server tsql sql-server-2008 hierarchyid


    【解决方案1】:

    我会让其他人解决您的具体问题,但我会告诉您,IMO,SQL Server 2008 中的 HierarchyId 并不是微软对 SQL Server 的最大贡献之一。它们很复杂,而且有些尴尬。我想您会发现,对于许多分层需求,公用表表达式 (CTE) 非常有用。

    兰迪

    【讨论】:

    • 我假设您指的是递归 CTE,因为 CTE 通常与层次结构无关。即使这样,这两个概念也不是相互排斥的,hierarchyid 的性能比我见过的任何其他方法都要好得多(当索引和使用正确时)。 hierarchyid 列还可以与其他嵌套集类型的列组合,以执行具有索引搜索性能的非常复杂的分层查询。我会说你的批评是没有根据的; hierarchyid 实际上是 SQL 2008 中使用最少的数据类型之一。
    • 它不仅没有得到充分利用,而且还没有得到充分的支持。 LinqtoSQL 或实体框架中不支持 HierarchyId(dbml 设计器不会触及它们)。即使在 VS 2010 RC 中也是如此。
    • 对于我们中的一些人来说,HierarchyId 是 SQL 的一个非常需要的补充。它消除了对许多递归查询的需求,并且在正确使用时可以显着提高性能。
    • 对于那些通过使用 ORM 和实体框架遇到 HierarchID 问题的好人,难道不是一个好的老式参数化存储过程可以解决问题吗?而且,不......这不像你必须重新发明轮子...... BOL 有很多可以轻松转换的示例。
    【解决方案2】:

    这些十六进制值只是层次结构级别的二进制表示。一般来说,您不应该直接使用它们。

    您可能想查看以下示例,我认为该示例应该是不言自明的。我希望它能让你朝着正确的方向前进。

    创建一个带有hierarchyid 字段的表:

    CREATE TABLE groups (
        group_name       nvarchar(100)  NOT NULL,
        group_hierarchy  hierarchyid    NOT NULL
    );
    

    插入一些值:

    INSERT INTO groups (group_name, group_hierarchy)
    VALUES
        ('root',     hierarchyid::Parse('/')),
        ('domain-a', hierarchyid::Parse('/1/')),
        ('domain-b', hierarchyid::Parse('/2/')),
        ('sub-a-1',  hierarchyid::Parse('/1/1/')),
        ('sub-a-2',  hierarchyid::Parse('/1/2/'));
    

    查询表:

    SELECT 
        group_name,
        group_hierarchy.ToString()
    FROM
        groups
    WHERE
        (group_hierarchy.IsDescendantOf(hierarchyid::Parse('/1/')) = 1);
    

    【讨论】:

      【解决方案3】:

      Adam Milazzo 在这里写了一篇关于hierarchyid 内部结构的精彩文章:

      http://www.adammil.net/blog/view.php?id=100

      简而言之,使用直接十六进制的东西没有意义,而是将数字转换为二进制。原因是事物并没有在偶数字节边界上被分割。如果它是前四个节点之一,则表示单个节点可以短至 5 位。随着使用更多节点变得越来越长,接下来的 4 个节点每个 6 位,接下来的 8 个节点每个 7 位,然后跳到接下来的 64 个节点每个 12 位!接下来的 1024 个每个最多 18 位。

      我需要将数据库转换为 Postgres,并编写了一个解析这些十六进制值的脚本。你可以在这里查看我为 AdventureWorks 制作的版本,搜索“hierarchyid”:

      https://github.com/lorint/AdventureWorks-for-Postgres/blob/master/install.sql

      【讨论】:

        猜你喜欢
        • 2011-02-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多