Мова XQuery

Одним з недоліків мови XPath є те, що він у своїй основі являє собою просто механізм адресації застосовувані в ньому позначення шляхи дозволяють переходити за існуючими вузлам в ієрархії, але не дають можливості формувати вузли, які ще не існують Іншими словами, мова XPath трохи нагадує реляційний мова (тут слово реляційний укладена в лапки, оскільки справжні реляційні мови, безумовно, не є навігаційними) в тому сенсі, що він підтримує операції скорочення і проекції, але не операції соедіненія19 Саме ця причина почасти послужила стимулом до створення мови XQuery порівняно з мовою Xpath одним з основних доповнень, передбачених у мові XQuery, якраз і є здатність формувати нові вузли

Така можливість ілюструється у наведеному нижче першому прикладі І в даному випадку передбачається, що існує документ XML, званий PartsRelation, точно такий же, як і в попередньому підрозділі Припустимо також, що маються структуровані аналогічним чином документи SuppliersRelation і ShipmentsRelation Таким чином, нижче наведена формулювання на мові XQuery сле дме запиту: Для кожної поставки визначити імя постачальника, імя деталі і обєк ем поставки.

&ltResult&gt

{ for $spx in document(&quotShipmentsRelationxml&quot)

//ShipmentTuple,                                                                                                                                                                     

$sx in document(&quotSuppliersRelationxml&quot)

//SupplierTuple[SNUM = $spx/SNUM] ,

$px in document(&quotPartsRelationxml&quot)

//PartTuple[PNUM = $spx/PNUM] order by SNAME,

PNAME return

&ltResultTuple&gt

{ $SX/SNAME, $px/PNAME, $spx/QTY }

&lt/ResultTuple&gt }

&lt/Result&gt

Пояснення

1 В цілому це вираз обчислює (Формує) єдиний елемент Result, що містить послідовність елементів ResultTuple В якості додаткового зауваження відзначимо, що якби були видалені охоплюють цей вираз

19 Це твердження певною мірою є занадто спрощеним фактично мова XPath підтримує свого роду операцію декартова твори (яка, безумовно, представляє собою вироджений випадок операції зєднання) Але ця мова не підтримує операції зєднання в будь-якої більш загальній формі

дескриптори Result, то залишився вираз і раніше представляло б собою допустимий запит XQuery, але повертало результат, який не є формально правильним

2 Зручний спосіб пояснення семантики всього цього виразу (за винятком охоплюють дескрипторів Result) полягає у використанні наступного його аналога – вирази реляційного числення

{ SXSNAME, PXPNAME, SPXQTY } WHERE SXSNUM = SPXSNUM AND PXPNUM = SPXPNUM

Це вираз фактично вимагає виконання зазначеного зєднання відносин постачальників, деталей і поставок, а потім отримання проекції результату цього зєднання за атрибутами SNAME, PNAME І QTY

Примітка Тут не показаний аналог кроку order by в запиті XQuery, оскільки операція впорядкування order by не є реляційної Крім того, застосовуються звичайно прийняті в цій книзі угоди, що стосуються імен змінних області значень (SX, PX і SPX – змінні області значень, що пробігають, відповідно, по відносинам постачальників, деталей і поставок) Нарешті, ігнорується той факт, що в реляційних виразах дублікати кортежів усуваються автоматично, а у виразах XQuery – ні

3 На підставі викладеного в попередньому абзаці можна зробити висновок, що пере менниє $ sx, $ px і $ spx мови XQuery діють певною мірою ана логічно змінним області значень в реляційному численні Але така аналогія є не зовсім точною і здатна збити з пантелику формулювання запиту XQuery насправді не так вже схожа на реляційну, оскільки цілком очевидно, що вона за своїм характером є повністю процедурної (у цьому звязку рекомендуємо ознайомитися з анотацією до [273]) Насправді формулювання запиту XQuery вельми нагадує наведену нижче формулювання запиту у вигляді вкладених циклів (тут вона представлена ​​на псевдокоде, а як роздільник використовується .”, а не /)

do for each shipment $spx

do for each supplier $sx where Ssxsnum = $spxsnum

;                                        do for each part $px where $pxpnum =

$spxpnum                                            emit { $sx SNAME, $px PNAME,

$spxQTY }

end do                                           end do

З цього випливає, що фактично змінні $ sx, $ px і $ spx набагато більше нагадують змінні управління циклом (визначені в тому ж сенсі, як і в звичайному мові програмування), ніж змінні області значень Більш того, слід зазначити, що ітерацію по кортежам відносини поставок довелося виконувати саме в зовнішньому циклі це означає, що спочатку довелося ввести в дію змінну управління циклом $ spx, оскільки дві інші змінні визначені в термінах цієї змінної Такий факт може спричинити деякі цікаві наслідки з точки зору організації роботи оптимізатора На відміну від неї, дві інші змінні, $ sx і $ рх, можуть бути введені в будь-якому порядку Тим не менше, питання про те, чи робить порядок введення

цих змінних якийсь вплив на роботу оптимізатора, також може виявитися досить цікавим Принаймні, слід зазначити, що порядок, в якому вводяться ці змінні, впливає на то, в якому порядку виробляються результуючі елементи (див опис конструкції return в п 7) таким чином, взагалі кажучи, аналоги виразів A JOIN Bі B JOIN А мовою XQuery не є еквівалентними

На підставі наведених вище міркувань можна сміливо стверджувати, що XQuery фактично більшою мірою нагадує мову програмування, ніж мова запитів, призначений для кінцевого користувача

4 Тепер розглянемо, зокрема, конструкцію for, а саме ту частину конструк ції, яка передує першій коми Наведене нижче вираз віз обертає абстрактну (синтаксично проанализированную ) версію документа XML, який міститься у файлі ShipmentsRelationxml, з використанням як контекстного всього вузла документа

document(&quotShipmentsRelationxml&quot)

Специфікація / / ShipmentTuple свідчить про те, що нас цікавить елементи ShipmentTuple з даного документа, а специфікація for $ spx in вказує, що змінна $ spx повинна прийняти як своє значення кожен з цих кортежів поставок по черзі, в тому порядку, в якому вони при сутствуют в даному документі

5 Наступна частина конструкції for є аналогічною, за винятком того, що змінна $ sx приймає свої значення тільки серед тих постачальників, для яких значення SNUM одно поточним значенням $ spx

$sx in document (&quotSuppliersRelationxml&quot)

//SupplierTuple[SNUM = $spx/SNUM]

6 Остання частина конструкції for аналогічна описаній вище частини

7 Конструкція return виконується для кожної комбінації значень змінних

$ Sx, $ px і $ spx, в тому порядку, в якому ці значення виробляються конструкцією for Тому в даному прикладі конструкція return виробляє елементи ResultTuple в послідовності, яка визначається правилом, що значення $ рх змінюються найчастіше, значення $ sx змінюються менш часто, а значення $ spx змінюються найменш часто

8 Конструкція order by в основному не вимагає пояснень Але заслуговує вни манія те, що вона зявляється перед відповідною конструкцією return Таке розташування зазначених конструкцій дозволяє впорядковувати результати на підставі значень, які ще фактично не зявляються в результатах (як, наприклад, у запиті SELECT CITY FROM P ORDER BY WEIGHT мовою SQL) Але концептуально і в цьому випадку конструкція return повинна бути ви полнена в першу чергу, оскільки впорядкування неможливо виконати до тих пір, поки не зявиться щось, призначене для упорядкування

Нижче наведений другий приклад: Визначити номери деталей і загальний обсяг поставки для деталей, що поставляються двома або кількома постачальниками.

for $pnum in distinctvalues(document(&quotShipmentsRelationxml&quot)//PNUM) let $spx

:= document(&quotShipmentsRelationxml&quot)

//ShipmentTuple[PNUM =

$prium] where count ( $spx ) &gt 1 order by PNUM return

&ltResult&gt

{  $pnum,

&lttotqty&gt { sum ( $spx/gty ) } &lt/totqty&gt }

&lt/Result&gt

Пояснення

1 У даному прикладі показано повне вираз FLWOR (FLWOR – скорочення від for + let + where + order by + return воно вимовляється як слово flower – флауе)

2 Зверніть увагу на використання ключового слова distinct-values в конструкції for для усунення дублікатів номерів деталей змінна $ pnum приймає значення тільки серед різних номерів деталей в поставках

3 Конструкція let відрізняється від конструкції for тим, що задана в ній змінна не використовується для ітерацій по зазначеній послідовності значень замість цього такої змінної повністю присвоюється відповідна послідовність значень Крім того, в даному прикладі конструкція let обчислюється для кожного окремого номера деталі в постачанні по черзі, оскільки вона фактично вкладена в конструкцію for

4 Потім конструкція where викликає обчислення решти цього висловлю ня тоді і тільки тоді, коли поточна послідовність поставок (тобто після довність поставок з поточним номером деталі) має довжину більше одиниці підтримує звичайні агрегує оператори count, sum, avg, max і min

5 Слід знову зазначити, що все це вираження в цілому досить нагадує проце погане Аналог цього виразу на псевдокоде наведено нижче

do   for   each  distinct    shipment part   number   $pnum    

do for all    shipments   $spx  where   $spxpnum  =    $pnum     if    (    count  of   such  shipments   $spx    )    &gt   1   then

emit  {   $pnum,  sum  (   $spxqty  )    }   

end  if    end do    

end do    

Реляційний аналог даного виразу виглядає наступним чином

{ SPXPNUM, SUM ( SPY WHERE SPYPNUM = SPXPNUM, QTY ) } WHERE COUNT ( SPY WHERE SPYPNUM = SPXPNUM ) &gt 1

Тепер слід зазначити, що наведені вище приклади, можливо, є не зовсім реальними Це повязано з саме з тим, що вони за своїм характером певною мірою нагадують реляційні зокрема, в цих прикладах майже не враховується специфіка документів XML, які зазвичай мають ієрархічну структуру

Тому розглянемо наступний варіант застосовуваного проекту Спочатку припустимо, що документ PartsRelation є точно таким же, як і раніше Але припустимо, що замість документів SuppliersRelation І ShipmentsRelation тепер застосовується документ SuppliersOverShipments, який характеризується описаними нижче особливостями

■ Кореневий елемент містить послідовність елементів Supplier

■ Кожен елемент Supplier включає елементи SNUM, SNAME, STATUS і CITY, за якими розташована послідовність елементів shipment

■ Кожен елемент Shipment містить елемент PNUM і елемент QTY

Структура цього документа показана на рис 274

Тепер розглянемо запити: Визначити постачальників, які постачають деталь Р2 і Визначити деталі, що поставляються постачальником S2. Нижче наведені реляційні формулювання цих запитів

SX WHERE EXISTS SPX ( SPXSNUM = SX SNUM AND SPXPNUM = P2 )

PX WHERE EXISTS SPX ( SPXPNUM = PXPNUM AND SPXSNUM = S2 )

Примітка Для спрощення передбачається, що значення SNUM і PNUM представляють собою прості символьні рядки, а не значення якогось визначається користувачем типу Отже, нижче наведена формулювання першого запиту на язикеХО_іегу

for $sx in document(&quotSuppliersOverShipmentsxml&quot)//Supplier where $sx//PNUM = &quotP2&quot

return

&ltResult&gt

{ $SX//SNUM, $sx//SNAME, $sx//STATUS, $Sx//CITY }

&lt/Result&gt

А формулювання другого запиту на мові XQuery виглядає наступним чином

let $sx := document(&quotSuppliersOverShipmentsxml&quot)

//Supplier[SNUM = &quotS2&quot] return &ltResult&gt

{ document(&quotPartsRelationxml&quot)

//PartTuple[PNUM = $sx//PNUM]

} &lt/Result&gt

Цілком очевидно, що формулювання XQuery виявилися менш симетричними в порівнянні з їх реляційними аналогами, але цього і слід було очікувати через асиметричного (ієрархічного) характеру проекту XML

На завершення даного розділу наведемо ще кілька зауважень

■ Як і в спочатку сформульованої версії мови SQL [49] – [411], у мові XQuery відсутня явна підтримка операції зєднання І дійсно, в [2729] конкретно вказано, що для обчислення сполук можуть застосовуватися [вираження FLWOR]; під цим по суті мається на увазі, що при обчисленні кожного зєднання користувач повинен вказувати необхідну для цього послідовність кроків Але мова XQuery включає явну підтримку операцій обєднання, перетину і різниці (конструкція except) з усуненням дублікатів

включає також явну підтримку кванторів існування та загальності Нижче наведені відповідні приклади

some $x in ( 2, 4, 8 ) satisfies $x &lt

7 every $x in ( 2, 4, 8 ) satisfies $x

&lt 7

Перше з цих висловів приймає істинне значення, а друге-помилкове

■ Як описано в розділах 7 і 8, з реляційною моделлю повязано (дуже важливе) поня тя повноти Мабуть, аналогічного поняття не існує ні в мові XQuery, ні в мові XML в целом20

Джерело: Дейт К Дж, Введення в системи баз даних, 8-е видання: Пер з англ – М: Видавничий дім «Вільямс», 2005 – 1328 с: Ил – Парал тит англ

Схожі статті:


Сподобалася стаття? Ви можете залишити відгук або підписатися на RSS , щоб автоматично отримувати інформацію про нові статтях.

Коментарів поки що немає.

Ваш отзыв

Поділ на параграфи відбувається автоматично, адреса електронної пошти ніколи не буде опублікований, допустимий HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*

*