XML и индексирование

Cotton
Дата: 10.10.2015 20:51:39
Здравствуйте.
Есть таблица index_xml, в которой в поле xmltype хранится xml следующего вида:
<DATA>
   <FIRST_NAME>fn55</FIRST_NAME>
   <LAST_NAME>ln55</LAST_NAME>
   <STREET>street55</STREET>
   ...
</DATA>

Хочется ускорить выборку из этой таблицы, создав индекс по выбираемым значением. В случае XML со статическим набором тегов можно было создать индекс по каждому из тегов, типа extractvalue(context,'DATA/TAG_NAME'). Но XML может изменяться. Каким образом можно универсально проиндексировать хранимые значения?

Код таблицы:
create table index_xml (id number, context xmltype);
insert into index_xml (id, context1)
 select level, xmltype('<DATA><FIRST_NAME>fn'||level||'</FIRST_NAME><LAST_NAME>ln'||level||'</LAST_NAME><STREET>street'||level||'</STREET></DATA>')
   from dual 
   connect by level < 10000;
Cotton
Дата: 10.10.2015 20:55:27
Версия Oracle 10.2.0.4.
mcureenab
Дата: 10.10.2015 21:08:32
Cotton
Но XML может изменяться.


Структура таблиц тоже может изменяться время от времени. Тогда применяют DDL, получают нужную структуру и дальше работают.
Структура вообще не определена или она иногда меняется?
Какие значения нужно индексировать?
Cotton
Дата: 10.10.2015 21:12:46
mcureenab, по сути, структура равна указанной, но новые теги могут добавляться (на уровне ...). поиск будет происходить и по ним.
Cotton
Дата: 10.10.2015 21:20:05
еще раз, попытаюсь объяснить детально. информация хранится в виде XML. Будет производиться поиск по всей таблице, где в теге FIRST_NAME поля XML хранится значение fn55, например. В текущем виде происходит full scan. При использовании индекса extractvalue(context,'DATA/FIRST_NAME ') скорость заметно вырастает. Но дело в том, что перечень тегов (FIRST_NAME, LAST_NAME) не статична. И если завтра будет добавлен тег SECOND_NAME снова будет происходить full scan таблицы. Поэтому логично, что хочется иметь некий универсальный индекс, до которого я пока додуматься не могу.

возможен еще вариант с такой структурой для универсализации тегов:
<DATA>
   <COL name="FIRST_NAME">fn55</COL>
   <COL name="LAST_NAME">ln55</COL>
   <COL name="STREET">street55</COL>
   ...
</DATA>
mcureenab
Дата: 10.10.2015 21:20:13
Cotton
mcureenab, по сути, структура равна указанной, но новые теги могут добавляться (на уровне ...). поиск будет происходить и по ним.

Непонятно. Примеры запросов нарисуйте. Это типа тэг такой, значение такое и тэг такой, значение такое?
Если искать по чем попало, то Text индексы нужно строить.
Cotton
Дата: 10.10.2015 21:26:46
-- создание таблицы, данные
create table index_xml (id number, context xmltype);
insert into index_xml (id, context1)
 select level, xmltype('<DATA><FIRST_NAME>fn'||level||'</FIRST_NAME><LAST_NAME>ln'||level||'</LAST_NAME><STREET>street'||level||'</STREET></DATA>')
   from dual 
   connect by level < 10000;
-- примеры запросов
select *
   from index_xml t
   where extractvalue(t.context1,'/DATA/FIRST_NAME') = 'fn21';
select *
   from index_xml t
   where extractvalue(t.context1,'/DATA/STREET') = 'street31';
-- запрос, который может потребовать в будущем
select *
   from index_xml t
   where extractvalue(t.context1,'/DATA/SECOND_NAME') = 'street31';
mcureenab
Дата: 10.10.2015 21:27:53
Cotton
И если завтра будет добавлен тег SECOND_NAME снова будет происходить full scan таблицы. Поэтому логично, что хочется иметь некий универсальный индекс, до которого я пока додуматься не могу.


Появится SECOND_NAME пропишите его в структуру, постройте индекс. В чем проблема то? Обычное изменение структуры БД. Если надо, GUI сделайте чтобы администратору системы комфортно было.
Cotton
Дата: 10.10.2015 21:31:50
mcureenab, увы, заказчик настаивает на универсализме. иначе бы я не искал решения.
mcureenab
Дата: 10.10.2015 21:37:44
Если полная универсальность нужна и структуру БД вообще никак нельзя менять, вам в на Text индексы следует посмотреть. Для оптимизации можно свой лексический разбор делать, чтобы лексемы получались вида (тэг, значение). Ненужные тэги можно не индексировать. Имена тэгов можно закодировать числами.