【问题标题】:Copy in adjacency model邻接模型中的复制
【发布时间】:2010-11-25 20:22:41
【问题描述】:

我需要创建一个复制邻接模型中节点的 sql 存储过程 (Sql Server 2008 - T-SQL)。

表格可以看作有两列,Id 和 ParentId(FK 到 Id)。复制意味着所有的下属也需要复制。

我认为使用 WITH 是一个好的开始,但我很好奇是否可以在不使用 Cursors 的情况下完成此副本。

【问题讨论】:

    标签: sql sql-server-2008 adjacency-list


    【解决方案1】:

    邻接表的根本问题是在 SQL 中没有通用的方法来提取整个子树,因此您已经遇到了一个问题,即在不使用游标的情况下识别需要复制的所有行。

    如果可能,将您的邻接列表迁移到嵌套集模型,这样您就可以轻松识别子树的所有节点。但是,对于一般的插入和删除,嵌套集模型的维护比较复杂。

    编辑:正如“a_horse_with_no_name”所指出的,一种通用 SQL 处理邻接列表、递归公用表表达式的方法。

    【讨论】:

    • 好吧,我实际上是在将我的嵌套集模型转换为邻接列表,因为我们在插入节点时存在严重的性能问题(对于一个插入,平均需要完成 50.000 次更新)。
    • 我可以看到你对嵌套集模型有这么多插入的问题!在这种情况下,最好从数据库中读取列表并用其他语言处理它以生成必要的 SQL。
    • @Tony:一种在SQL中提取子树的通用方法,称为递归公用表表达式。
    • @a_horse_with_no_name:你是对的,递归 CTE 可用(指出这一点 +1)。我不得不承认我回答了一般 SQL 的问题,而不是 T-SQL(我意识到这个问题被标记为 SQL Server)。我刚刚搜索了递归 CTE,MS 页面有一个带有邻接列表的示例:msdn.microsoft.com/en-us/library/ms186243.aspx
    • @Tony:我想指出的是递归 CTE 通用 SQL。它不是特定于 SQL Server。所有主要的 DBMS(MySQL 除外)都支持它
    【解决方案2】:

    复制整个子树有点问题,因为当你复制你的子树时,你要么是

    • 反规范化数据或
    • 将其用作某种模板。

    在任何一种情况下,您都会在某些时候通过不一致的状态拖动数据 - 这表明您的设计存在一些问题(例如,您的记录是否需要有多个父项?如果是,那么您应该考虑重新设计)。

    因此,您应该使用更完整的示例来更新答案。

    一个解决方案是有一个临时表,选择插入应该不是问题,只是更新引用的 ID 会是一个问题。

    所以

    1. 插入临时表
    2. 更新 ID
    3. 插入到原始表中
    4. 删除临时记录

    该过程需要这样进行,因为在初始 WITH INSERT 中很难更改 ID(记录 ID 和引用父级的 ID)。但是,如果有一个很好的函数只依赖于 max_id 或只依赖于旧 ID,那么它是可能的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-09
      • 1970-01-01
      • 2013-01-24
      • 1970-01-01
      相关资源
      最近更新 更多