用于将嵌套XML数据与数据库表结构进行匹配的最快方法

时间:2012-10-01 13:32:06

标签: sql sql-server-2005 data-structures orm

我有一个创建datarequests的应用程序,这可能非常复杂。这些需要作为表存储在数据库中。 datarequest(作为XML)的大纲将是......

<datarequest>
  <datatask view="vw_ContractData" db="reporting" index="1">
    <datefilter modifier="w0">
      <filter index="1" datatype="d" column="Contract Date" param1="2009-10-19 12:00:00" param2="2012-09-27 12:00:00" daterange="" operation="Between" />
    </datefilter>
    <filters>
      <alternation index="1">
        <filter index="1" datatype="t" column="Department" param1="Stock" param2="" operation="Equals" />
      </alternation>
      <alternation index="2">
        <filter index="1" datatype="t" column="Department" param1="HR" param2="" operation="Equals" />
      </alternation>
      </filters>
    <series column="Turnaround" aggregate="avg" split="0" splitfield="" index="1">
      <filters />
    </series>
    <series column="Requested 3" aggregate="avg" split="0" splitfield="" index="2">
      <filters>
        <alternation index="1">
          <filter index="1" datatype="t" column="Worker" param1="Malcom" param2="" operation="Equals" />
        </alternation>          
      </filters>
    </series>
    <series column="Requested 2" aggregate="avg" split="0"  splitfield="" index="3">
      <filters />
    </series>
    <series column="Reqested" aggregate="avg" split="0" splitfield="" index="4">
      <filters />
    </series>
  </datatask>
</datarequest>

这对包含日期范围,主过滤器,系列和系列过滤器的数据请求进行编码。基本上任何具有index属性的元素都可以在其父元素中多次出现 - 例外情况是filter中的datefilter

但这种结构是一种学术性,问题更为根本:

当请求通过时,像这样的XML作为存储过程的参数发送到SQLServer。此XML被分解为非规范化表,然后迭代写入规范化表,例如tblDataRequest (DataRequestID PK)tblDataTasktblFiltertblSeries。这很好。

当我想将给定的XML定义与已在数据库中保存的XML定义匹配时,会出现问题。我目前这样做......

  • 将XML分解为非规范化表格
  • 使用CTE将数据库中的所有现有数据拉入同样的非规范化形式
  • 使用巨大的WHERE条件(34行长)匹配

..这将返回任何与给定XML完全匹配的DataRequestID。我担心这种方法最终会变得非常缓慢 - 部分是因为我不相信CTE会做任何巧妙的过滤,它会在应用巨大的{{1>之前每次拉出所有数据}}

我认为必须有更好的解决方案,例如

  • 存储WHERE时,还会以某种方式存储datarequest的哈希值并简单地匹配。在发生碰撞的情况下,请使用当前方法。但我想用set-logic做到这一点。而且,我担心XML中不相关的小差异会改变哈希 - 虚假空间等。
  • 以某种方式从下往上迭代地执行匹配。例如,生成一个在最低级别匹配的过滤器列表。将此作为datarequest的一部分用于匹配系列。使用它作为IN的一部分来匹配DataTasks等等。问题是,当我长时间考虑这个时,我开始停电。

基本上 - 有没有人曾经遇到过这种问题(他们必须有)。什么是解决它的推荐路线?示例(伪)代码会很棒:)

1 个答案:

答案 0 :(得分:1)

为了摆脱轻微差异的可能性,我将通过XML转换(XSLT)运行请求。

或者,因为您已经获得了将其解析为非规范化临时表的代码,这也很好。然后,我只需使用FOR XML创建一个新的XML文档。

您的目标是创建一个标准化的XML文档,该文档在适当的时候尊重排序,并在不合适的情况下消除不一致。

完成后,将其存储在新表中。现在,您可以将“标准化”请求XML与现有数据进行直接比较。

要进行实际比较,您可以使用哈希,将XML存储为字符串并进行直接字符串比较,或者执行完整的XML比较,如下所示:http://beyondrelational.com/modules/2/blogs/28/posts/10317/xquery-lab-36-writing-a-tsql-function-to-compare-two-xml-values-part-2.aspx

我的偏好,只要XML永远不会超过8000字节,就可以创建一个唯一的字符串(如果你有特殊的字符支持,可以是VARCHAR(8000)或NVARCHAR(4000))并在列上创建一个唯一的索引。