【问题标题】:Tree Structure With History in SQL ServerSQL Server 中具有历史记录的树结构
【发布时间】:2011-03-04 14:35:57
【问题描述】:

我不确定这是否是重复的问题,但我找不到关于这个主题的任何内容。

在表中存储树结构并能够存储该结构中的更改历史记录的最佳方法是什么。

感谢您的帮助。

更新:

我有 Employees 表,我需要将分支、部门、部分、子部分的结构存储在一个表中。 我需要存储员工分支机构、部门的历史信息,以便即使结构已更改,也能够检索员工的分支机构、部门、部门、子部门。

更新 2:

有一种解决方案可以在结构的每次更改时将整个结构保存在历史记录表中,但这是最好的方法吗?

更新 3:

还有订单表。我必须在每个订单上存储员工的职位、分支机构、部门、部门、子部门和其他。这是存储历史的主要原因。它会被经常使用。换句话说,我应该能够显示过去每一天的数据库数据。

更新 4:

也许使用 hierarchyid 是一种选择?

如果一个节点被重命名怎么办?如果我需要旧订单上的旧名称,我该怎么办?

【问题讨论】:

  • 可能有不止一张桌子
  • 没有“最佳方法”这样的东西,当前的解决方案是否能很好地解决需求,是否可扩展,是否简单,这些是我们在寻求解决方案时需要了解的问题跨度>
  • 我正在设计新的数据库结构,所以这只是我想到的一个解决方案。我的目标是在创建新数据库和更改软件之前找出是否有更好的选择。
  • 为什么需要历史记录中的信息类型?只是为了审核吗?是否进行分析,将表格从一个时间点与另一个时间点进行比较?例如,是否需要为某些会计或执行目的使用“最近几个月”图表的报告?结构多久会改变一次?信息的使用方式对模式建模的方式有很大影响。
  • @Thomas,我已经更新了我的问题。结构不经常改变。上个月、去年等有很多报告。

标签: sql sql-server tree history


【解决方案1】:

我认为您正在寻找类似的东西。它提供了一个完整的树形结构。这用于目录,但它可以用于任何内容:部门、部门、部分等。

历史是独立的,最好在考虑历史之前先了解一下节点结构。对于任何表的历史,只需要在 PK 中添加一个 DateTime 或 TimeStamp 列。历史存储在当前行的图像之前。

诸如 (a) 解析树的路径和 (b) 查找在某个时间点当前的相关历史记录行之类的功能是使用纯 SQL 执行的。使用 MS,您可以将递归 CTE 用于 (a),或在存储过程中编写更简单的形式。

对于 (b),我将实现表的派生版本(节点、部门等),它返回相关时间点的当前行;然后将其用于 (a) 的历史版本。

不必每次更改时都复制并保存整个树结构。

如果您需要任何说明,请随时提出问题。

数据模型

▶Tree Structure with History Data Model

不熟悉关系建模标准的读者可能会发现▶IDEF1X Notation 很有用。

【讨论】:

    【解决方案2】:

    根据历史信息的使用方式,将决定您需要临时解决方案还是仅需要审计解决方案。在时间解决方案中,您将存储给定节点在其给定位置应用的日期范围,并且“当前”层次结构是通过使用当前日期和时间来查询活动节点以得出层次结构的报告。说这是一个复杂的解决方案是轻描淡写的。

    鉴于我们谈论的是员工等级制度,我敢打赌,审计解决方案就足够了。在审计解决方案中,您有一个用于当前层次结构的表,并将更改存储在其他可访问的位置。应该注意的是,“其他地方”不一定是数据。如果不经常更改公司层次结构,那么您甚至可以使用技术含量极低的解决方案来创建公司层次结构的报告(或一系列报告)并将其存储为 PDF 格式。当有人想知道去年五月的层次结构是什么样子时,他们可以找到相应的 PDF 打印输出。

    但是,如果希望审计跟踪可查询,那么您可以考虑类似 SQL Server 2008 的更改跟踪功能或执行类似操作的第三方解决方案。

    请记住,“最好”的问题不仅仅是结构本身。对需要多少努力与其提供的功能进行成本效益分析。如果利益相关者需要随时查询层次结构并且它经常波动(不想在那里工作:))那么临时解决方案可能是最好的,但实施起来成本更高。如果层次结构不经常更改并且不需要进行细粒度审计,那么我倾向于简单地定期存储层次结构的 PDF。如果确实需要查询更改或需要细粒度审计,那么我会考虑使用审计工具。

    Change Tracking

    快速搜索一下,这里有几个第三方审计解决方案:

    ApexSQL

    Lumigent Technologies

    【讨论】:

    • 也许使用 hierarchyid 是一种选择?
    【解决方案3】:

    有几种方法,但是由于您的信息有限,我会说使用具有父关系的单表,对于历史记录,您可以简单地对表实施审计

    更新:根据你的新信息我不会使用单表数据存储,看起来你的层次结构比简单的树复杂得多,而且看起来你有一些很好结构的定义节点,特别是在进入部分和子部分之前的顶部;所以多表关系可能更合适;

    就审计表而言,有大量资源可以找出最适合您的方法,有按行和按列审计等。

    【讨论】:

    • 我已经更新了我的问题。您能否更具体地谈谈“实施表审计”?
    • 你的意思是每层都有一个表格?分支机构,部门,科室,子科室?以及表之间的关系?如果是这样,添加额外的层会很痛苦。我想要动态的树结构。
    • 这一切都取决于这些层的常见程度,如果它们非常相似,那么单个实体将起作用,否则我将使用单独的实体
    【解决方案4】:

    需要注意的一点是,您不必对树结构进行历史记录。它总是只会增长,永远不会变小。

    改变的是节点的使用。他们的数据可能会改变。

    例如一个网站。

    /a/b/c

    将永远存在。 A 可能是一个文件夹,b 也是,c 一个文件。后来a可能是一个folter,b一个墓碑(目前这里没有数据)作为c。但树本身永远不会改变。

    然后,添加一个版本号,并为每个节点添加一个历史/使用列表(节点类型),其中包含开始版本和可能(可以为空)结束版本。

    然后,用于显示版本 X 的代码可以轻松构建出此刻的“真实”树。

    为了支持节点的移动,有一个“rehook”类型,表明 noe 在这个版本中被移动到另一个项目。

    瞧。

    【讨论】:

    • 结构可能改变:例如,一个部门可能被取消或转移到不同分支机构的管辖范围内。或者可以合并其中的几个。
    • 不是树变化。节点使用的变化。正如我所说 - 您将用墓碑节点替换部门,或者用移动标记替换版本。 ID 层次结构不会改变。文件 /a/b/c 仍然是文件 /a/b/c,但使用方式不同。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多