一尘不染

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

sql

我有一个创建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可以在其父元素中出现多次属性-
所述例外是所述filterdatefilter

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

当请求通过时,像这样的XML作为存储的proc的参数发送到SQLServer。此XML切碎成一个反规范化的表,然后写入反复向规范化的表,如tblDataRequest (DataRequestID PK)tblDataTasktblFiltertblSeries。这可以。

当我想 将给定的XML定义与数据库中已保存的一个匹配 时,就会出现问题。我目前是通过…

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

..这将返回任何与给定XML完全匹配的DataRequestID。我担心这种方法最终会变得非常缓慢,部分原因是我不相信CTE会进行任何聪明的过滤,它会
应用大数据 之前 每次提取所有数据WHERE

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

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

基本上-有没有人曾经遇到过此类问题(他们必须有)。 推荐的解决方法是什么?示例(伪)代码将是巨大的:)


阅读 170

收藏
2021-03-08

共1个答案

一尘不染

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

另外,由于您已经有了将其解析为非规范化登台表的代码,所以也可以。然后,我将简单地使用FOR
XML
创建一个新的XML文档。

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

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

要进行实际的比较,您可以使用哈希,将XML存储为字符串并进行直接的字符串比较,或进行完整的XML比较,如下所示:http :
//beyondrelational.com/modules/2/blogs/28/帖子/ 10317 / xquery-
lab-36-编写一个tsql函数以比较两个xml值-
part-2.aspx

只要XML不会超过8000bytes,我的首选就是创建一个唯一的字符串(如果您有特殊字符支持,则为VARCHAR(8000)或NVARCHAR(4000))并在该列上创建一个唯一的索引。

2021-03-08