Самый быстрый способ сопоставления вложенных данных XML с структурой таблицы базы данных

У меня есть приложение, которое создает 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> 

Это кодирует datarequest, состоящий из фильтров, основных фильтров, серии и серии фильтров. В принципе, любой элемент, который имеет атрибут index может встречаться несколько раз в своем родительском элементе, исключение из которого является filter пределах filter datefilter .

Но структура этого рода носит академический характер, проблема более фундаментальна:

Когда запрос приходит, XML, подобный этому, отправляется SQLServer в качестве параметра для сохраненного proc. Этот XML измельчается в де-нормированную таблицу, а затем записывается итеративно в нормализованные таблицы, такие как tblDataRequest (DataRequestID PK) , tblDataTask , tblFilter , tblSeries . Это отлично.

Проблема возникает, когда я хочу соответствовать заданной ошибке XML с уже сохраненной в БД . В настоящее время я делаю это …

  • Измельчение XML в де-нормированную таблицу
  • Используя CTE, чтобы вытащить все существующие данные в базе данных в ту же деформированную форму
  • Согласование с использованием огромного условия WHERE (длиной 34 строки)

.. Это вернет мне любой DataRequestID, который точно соответствует предоставленному XML. Я боюсь, что этот метод в конечном итоге будет болезненно медленным – отчасти потому, что я не верю, что CTE будет делать любую умную фильтрацию, он будет вытаскивать все данные каждый раз, прежде чем применять огромные WHERE .

Я думал, что для этого должны быть более эффективные решения.

  • При хранении datarequest также datarequest хэш-файл данных как-то и просто сопоставляйте это. В случае столкновения используйте текущий метод. Однако я хотел сделать это с помощью set-logic. А также, меня беспокоят нерелевантные небольшие различия в XML, изменяющие хеш-ложные пространства и т. Д.
  • Как-то выполнить сопоставление итеративно снизу вверх. Например, создайте список фильтров, которые соответствуют самому низкому уровню. Используйте это как часть IN для соответствия Series. Используйте это как часть IN для соответствия DataTasks и т. Д. Проблема заключается в том, что я начинаю сглаживать, когда думаю об этом слишком долго.

В основном – кто-нибудь когда-либо сталкивался с такой проблемой раньше (они должны иметь). И какой будет рекомендуемый маршрут для его решения? пример (псевдо) код будет большим 🙂

Чтобы избавиться от возможности незначительных различий, я бы выполнил запрос через XML-преобразование (XSLT).

В качестве альтернативы, поскольку у вас уже есть код для разбора этого в денормализованную промежуточную таблицу, это тоже хорошо. Затем я просто использовал FOR XML для создания нового XML-документа.

Ваша цель здесь – создать стандартизованный XML-документ, который будет уважать порядок, где это уместно, и устраняет несогласованности там, где это не так.

Как только это будет сделано, сохраните это в новой таблице. Теперь вы можете запустить прямое сравнение «стандартизованного» запроса XML с существующими данными.

Чтобы выполнить фактическое сравнение, вы можете использовать хэш, хранить XML в виде строки и выполнять прямое сравнение строк или выполнить полное сравнение XML следующим образом: http://beyondrelational.com/modules/2/blogs/28/ сообщения / 10317 / XQuery-ЛАБ-36-писание-а-БЛИЦ-функция к Compare-два XML-значениям частей-2.aspx

Мое предпочтение, поскольку XML никогда не превышает 8000 байт, было бы создать уникальную строку (либо VARCHAR (8000), либо NVARCHAR (4000), если у вас есть специальная поддержка символов) и создать уникальный индекс в столбце.