Univerzální B-stromy (UB-Stromy) Vícerozměrná přístupová metoda Rudolf Bayer Michal Krátký, michal.kratky@vsb.cz http://www.cs.vsb.cz/kratky
Obsah Úvod Vícerozměrná data Principy UB-stromů Algoritmus vkládání bodu Algoritmus výpočtu Z-adresy Algoritmus rozsahového dotazu Práce s nebodovými objekty Složitosti algoritmů, výhody
Úvod UB-strom je vícerozměrná přístupová metoda autorem je Rudolf Bayer, další výzkum Volker Markl Využívá Z-uspořádání a B-stromů
Vícerozměrná data Kartézským součinem domén atributů vznikne vícerozměrný prostor n-tice (řádek, tuple, entita, objekt) je bodem v n-dimenzionálním prostoru a je takto indexován Prostorová blízkost umožňuje shlukování těchto bodů pro uložení na diskové stránky => snížení počtu přístupů na disk => rychlejší operace Využití v data warehousingu, GIS, ...
Z-uspořádání Pro x Î W a binární reprezentaci každého atributu xi = x i,s-1 x i,s-2 ... x i,0 definujeme Z-hodnotu Z(x): Z(x) počítá pro každou n-tici Z-adresu (tj. jeho pozici na Z-křivce) Z-hodnoty jsou efektivně počítány tzv. bitovým prokládáním (bit-interleaving) Z(x) je bijektivní funkce, která počítá pro každý bod jeho Z-adresu (tj. pozici na Z-křivce).
Z-uspořádání pro univerzum 8x8 1 5 4 17 16 21 20 3 2 7 6 19 18 23 22 9 8 13 12 25 24 29 28 11 10 15 14 27 26 31 30 33 32 37 36 49 48 53 52 35 34 39 38 51 50 55 54 41 40 45 44 57 56 61 60 43 42 47 46 59 58 63 62 (a) (b)
Z-region [a :b ] je prostor pokrytý intervalem na Z-křivce. Z-regiony/UB-stromy Z-region [a :b ] je prostor pokrytý intervalem na Z-křivce. UB-Stromové dělení: [0 : 3],[4 : 20], [21 : 35], [36 : 47], [48 : 63] Z-region [4 : 20] 4 20
UB-strom V uzlu B-stromu jsou uloženy adresy Z-regionů UB-index UB-soubor K Z-regionu koresponduje jedna disková stránka. V listech B-stromu jsou uloženy n-tice náležící k danému Z-regionu
Algoritmus vkládání bodu Vstup: x: bod, který má být vložen do UB-Stromu Výstup: žádný x = Z(x) find [a : g] in the UB-Tree, such that a Ł x Ł g retrieve page(a : g) insert x into page(a : g) if count(a : g) > C choose bÎ[a : g], so that ½C - e Ł count(a : b) Ł ½C + e split page(a : g) into page(a : b) and page(b + 1 : g) end if C je maximální počet bodů, které mohou být uloženy v jedné stránce. x je vložen do listu-stránky příslušející k Z-regionu, který je nalezen bodovým dotazem.
Ukázka vkládání bodů
Zaddress za = Z(tuple); BtreeInsert(za, tuple); } Zdrojový kód Insert(Tuple tuple) { Zaddress za = Z(tuple); BtreeInsert(za, tuple); } Ubvalue findSplitPoint(Tuple t1, Tuple t2) /* nalezení optimální Z-adresy mezi t1 a t2 */ UB-Strom B-Strom Z-adresa
Zaddress za = Z(tuple); BtreeInsert(za, tuple); } Zdrojový kód Insert(Tuple tuple) { Zaddress za = Z(tuple); BtreeInsert(za, tuple); } Ubvalue findSplitPoint(Tuple t1, Tuple t2) /* nalezení optimální Z-adresy mezi t1 a t2 */ UB-Strom B-Strom Z-adresa
Zaddress za = Z(tuple); BtreeInsert(za, tuple); } Zdrojový kód Insert(Tuple tuple) { Zaddress za = Z(tuple); BtreeInsert(za, tuple); } Ubvalue findSplitPoint(Tuple t1, Tuple t2) /* nalezení optimální Z-adresy mezi t1 a t2 */ UB-Strom B-Strom Z-adresa
Zaddress za = Z(tuple); BtreeInsert(za, tuple); } Zdrojový kód Insert(Tuple tuple) { Zaddress za = Z(tuple); BtreeInsert(za, tuple); } Ubvalue findSplitPoint(Tuple t1, Tuple t2) /* nalezení optimální Z-adresy mezi t1 a t2 */ UB-Strom B-Strom Z-adresa
Po vložení dalších dvou bodů ...
Zaddress za = Z(tuple); BtreeInsert(za, tuple); } Zdrojový kód Insert(Tuple tuple) { Zaddress za = Z(tuple); BtreeInsert(za, tuple); } Ubvalue findSplitPoint(Tuple t1, Tuple t2) /* nalezení optimální Z-adresy mezi t1 a t2 */ UB-Strom B-Strom Z-adresa
Zaddress za = Z(tuple); BtreeInsert(za, tuple); } Zdrojový kód Insert(Tuple tuple) { Zaddress za = Z(tuple); BtreeInsert(za, tuple); } Ubvalue findSplitPoint(Tuple t1, Tuple t2) /* nalezení optimální Z-adresy mezi t1 a t2 */ UB-Strom B-Strom Z-adresa
Zaddress za = Z(tuple); BtreeInsert(za, tuple); } Zdrojový kód Insert(Tuple tuple) { Zaddress za = Z(tuple); BtreeInsert(za, tuple); } Ubvalue findSplitPoint(Tuple t1, Tuple t2) /* nalezení optimální Z-adresy mezi t1 a t2 */ UB-Strom B-Strom Z-adresa
Zaddress za = Z(tuple); BtreeInsert(za, tuple); } Zdrojový kód Insert(Tuple tuple) { Zaddress za = Z(tuple); BtreeInsert(za, tuple); } Ubvalue findSplitPoint(Tuple t1, Tuple t2) /* nalezení optimální Z-adresy mezi t1 a t2 */ UB-Strom Z-adresa B-Strom
Zaddress za = Z(tuple); BtreeInsert(za, tuple); } Zdrojový kód Insert(Tuple tuple) { Zaddress za = Z(tuple); BtreeInsert(za, tuple); } Ubvalue findSplitPoint(Tuple t1, Tuple t2) /* nalezení optimální Z-adresy mezi t1 a t2 */ UB-Strom Z-adresa B-Strom
Zaddress za = Z(tuple); BtreeInsert(za, tuple); } Zdrojový kód Insert(Tuple tuple) { Zaddress za = Z(tuple); BtreeInsert(za, tuple); } Ubvalue findSplitPoint(Tuple t1, Tuple t2) /* nalezení optimální Z-adresy mezi t1 a t2 */ UB-Strom Z-adresa B-Strom
Zaddress za = Z(tuple); BtreeInsert(za, tuple); } Zdrojový kód Insert(Tuple tuple) { Zaddress za = Z(tuple); BtreeInsert(za, tuple); } Ubvalue findSplitPoint(Tuple t1, Tuple t2) /* nalezení optimální Z-adresy mezi t1 a t2 */ UB-Strom Z-adresa B-Strom
Zaddress za = Z(tuple); BtreeInsert(za, tuple); } Zdrojový kód Insert(Tuple tuple) { Zaddress za = Z(tuple); BtreeInsert(za, tuple); } Ubvalue findSplitPoint(Tuple t1, Tuple t2) /* nalezení optimální Z-adresy mezi t1 a t2 */ UB-Strom Z-adresa B-Strom
Zaddress za = Z(tuple); BtreeInsert(za, tuple); } Zdrojový kód Insert(Tuple tuple) { Zaddress za = Z(tuple); BtreeInsert(za, tuple); } Ubvalue findSplitPoint(Tuple t1, Tuple t2) /* nalezení optimální Z-adresy mezi t1 a t2 */ UB-Strom Z-adresa B-Strom
Zaddress za = Z(tuple); BtreeInsert(za, tuple); } Zdrojový kód Insert(Tuple tuple) { Zaddress za = Z(tuple); BtreeInsert(za, tuple); } Ubvalue findSplitPoint(Tuple t1, Tuple t2) /* nalezení optimální Z-adresy mezi t1 a t2 */ UB-Strom Z-adresa B-Strom
Zaddress za = Z(tuple); BtreeInsert(za, tuple); } Zdrojový kód Insert(Tuple tuple) { Zaddress za = Z(tuple); BtreeInsert(za, tuple); } Ubvalue findSplitPoint(Tuple t1, Tuple t2) /* nalezení optimální Z-adresy mezi t1 a t2 */ UB-Strom Z-adresa B-Strom
UB-Strom Z-adresa B-Strom UB-Strom Z-adresa B-Strom
UB-Strom Z-adresa B-Strom UB-Strom Z-adresa B-Strom
Zaddress za = Z(tuple); BtreeInsert(za, tuple); } Zdrojový kód Insert(Tuple tuple) { Zaddress za = Z(tuple); BtreeInsert(za, tuple); } Ubvalue findSplitPoint(Tuple t1, Tuple t2) /* nalezení optimální Z-adresy mezi t1 a t2 */ UB-Strom Z-adresa B-Strom
Zaddress za = Z(tuple); BtreeInsert(za, tuple); } Zdrojový kód Insert(Tuple tuple) { Zaddress za = Z(tuple); BtreeInsert(za, tuple); } Ubvalue findSplitPoint(Tuple t1, Tuple t2) /* nalezení optimální Z-adresy mezi t1 a t2 */ UB-Strom Z-adresa B-Strom
Zaddress za = Z(tuple); BtreeInsert(za, tuple); } Zdrojový kód Insert(Tuple tuple) { Zaddress za = Z(tuple); BtreeInsert(za, tuple); } Ubvalue findSplitPoint(Tuple t1, Tuple t2) /* nalezení optimální Z-adresy mezi t1 a t2 */ UB-Strom Z-adresa B-Strom
Po vložení dalších bodů obsahuje UB-strom 5 Z-regionů ..
Zaddress za = Z(tuple); BtreeInsert(za, tuple); } Zdrojový kód Insert(Tuple tuple) { Zaddress za = Z(tuple); BtreeInsert(za, tuple); } Ubvalue findSplitPoint(Tuple t1, Tuple t2) /* nalezení optimální Z-adresy mezi t1 a t2 */ UB-Strom Z-adresa B-Strom
Zaddress za = Z(tuple); BtreeInsert(za, tuple); } Zdrojový kód Insert(Tuple tuple) { Zaddress za = Z(tuple); BtreeInsert(za, tuple); } Ubvalue findSplitPoint(Tuple t1, Tuple t2) /* nalezení optimální Z-adresy mezi t1 a t2 */ UB-Strom Z-adresa B-Strom
Zaddress za = Z(tuple); BtreeInsert(za, tuple); } Zdrojový kód Insert(Tuple tuple) { Zaddress za = Z(tuple); BtreeInsert(za, tuple); } Ubvalue findSplitPoint(Tuple t1, Tuple t2) /* nalezení optimální Z-adresy mezi t1 a t2 */ UB-Strom Z-adresa B-Strom
Zaddress za = Z(tuple); BtreeInsert(za, tuple); } Zdrojový kód Insert(Tuple tuple) { Zaddress za = Z(tuple); BtreeInsert(za, tuple); } Ubvalue findSplitPoint(Tuple t1, Tuple t2) /* nalezení optimální Z-adresy mezi t1 a t2 */ UB-Strom Z-adresa B-Strom
Zaddress za = Z(tuple); BtreeInsert(za, tuple); } Zdrojový kód Insert(Tuple tuple) { Zaddress za = Z(tuple); BtreeInsert(za, tuple); } Ubvalue findSplitPoint(Tuple t1, Tuple t2) /* nalezení optimální Z-adresy mezi t1 a t2 */ UB-Strom Z-adresa B-Strom
A po vložení dalších bodů ...
Zaddress za = Z(tuple); BtreeInsert(za, tuple); } Zdrojový kód Insert(Tuple tuple) { Zaddress za = Z(tuple); BtreeInsert(za, tuple); } Ubvalue findSplitPoint(Tuple t1, Tuple t2) /* nalezení optimální Z-adresy mezi t1 a t2 */ UB-Strom Z-adresa B-Strom
Zaddress za = Z(tuple); BtreeInsert(za, tuple); } Zdrojový kód Insert(Tuple tuple) { Zaddress za = Z(tuple); BtreeInsert(za, tuple); } Ubvalue findSplitPoint(Tuple t1, Tuple t2) /* nalezení optimální Z-adresy mezi t1 a t2 */ UB-Strom Z-adresa B-Strom
Zaddress za = Z(tuple); BtreeInsert(za, tuple); } Zdrojový kód Insert(Tuple tuple) { Zaddress za = Z(tuple); BtreeInsert(za, tuple); } Ubvalue findSplitPoint(Tuple t1, Tuple t2) /* nalezení optimální Z-adresy mezi t1 a t2 */ UB-Strom Z-adresa B-Strom
Výpočet Z-adresy
1 0 0 1 0 _ _ _ _ _ _ _ _ _ _ 1 1 0 0 1 1 _ _ _ _ _ _ _ _ _ _ Zdrojový kód UB-strom Zaddress Z(Tuple tuple) { Zaddress za = 0; int pos = 0, bit ; for (bit = 0; bit < maxbits(tuple); bit++) foreach attribute of tuple do if (attribute[bit] exists) { if (attribute[bit] is set) ZaddressSetBit(&za, pos); pos++; } return za; Atribut 1 Atribut 2 (25,18) Z-adresa Atribut 2 Atribut 1 1 0 0 1 0 _ _ _ _ _ _ _ _ _ _ 1 1 0 0 1 Bitové řetězce 1 _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ Z-adresa
1 0 0 1 0 _ _ _ _ _ _ _ _ _ _ 1 1 0 0 1 1 1 _ _ _ _ _ _ _ _ _ _ Zdrojový kód UB-strom Zaddress Z(Tuple tuple) { Zaddress za = 0; int pos = 0, bit ; for (bit = 0; bit < maxbits(tuple); bit++) foreach attribute of tuple do if (attribute[bit] exists) { if (attribute[bit] is set) ZaddressSetBit(&za, pos); pos++; } return za; Atribut 1 Atribut 2 (25,18) Z-adresa Atribut 2 Atribut 1 1 0 0 1 0 _ _ _ _ _ _ _ _ _ _ 1 1 0 0 1 Bitové řetězce 1 1 _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ Z-adresa
1 0 0 1 0 _ _ _ _ _ _ _ _ _ _ 1 1 0 0 1 1 1 0 _ _ _ _ _ _ _ _ _ _ Zdrojový kód UB-strom Zaddress Z(Tuple tuple) { Zaddress za = 0; int pos = 0, bit ; for (bit = 0; bit < maxbits(tuple); bit++) foreach attribute of tuple do if (attribute[bit] exists) { if (attribute[bit] is set) ZaddressSetBit(&za, pos); pos++; } return za; Atribut 1 Atribut 2 (25,18) Z-adresa Atribut 2 Atribut 1 1 0 0 1 0 _ _ _ _ _ _ _ _ _ _ 1 1 0 0 1 Bitové řetězce 1 1 0 _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ Z-adresa
1 0 0 1 0 _ _ _ _ _ _ _ _ _ _ 1 1 0 0 1 1 1 0 1 _ _ _ _ _ _ _ _ _ _ Zdrojový kód UB-strom Zaddress Z(Tuple tuple) { Zaddress za = 0; int pos = 0, bit ; for (bit = 0; bit < maxbits(tuple); bit++) foreach attribute of tuple do if (attribute[bit] exists) { if (attribute[bit] is set) ZaddressSetBit(&za, pos); pos++; } return za; Atribut 1 Atribut 2 (25,18) Z-adresa Atribut 2 Atribut 1 1 0 0 1 0 _ _ _ _ _ _ _ _ _ _ 1 1 0 0 1 Bitové řetězce 1 1 0 1 _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ Z-adresa
1 0 0 1 0 _ _ _ _ _ _ _ _ _ _ 1 1 0 0 1 1 1 0 1 0 _ _ _ _ _ _ _ _ _ _ Zdrojový kód UB-strom Zaddress Z(Tuple tuple) { Zaddress za = 0; int pos = 0, bit ; for (bit = 0; bit < maxbits(tuple); bit++) foreach attribute of tuple do if (attribute[bit] exists) { if (attribute[bit] is set) ZaddressSetBit(&za, pos); pos++; } return za; Atribut 1 Atribut 2 (25,18) Z-adresa Atribut 2 Atribut 1 1 0 0 1 0 _ _ _ _ _ _ _ _ _ _ 1 1 0 0 1 Bitové řetězce 1 1 0 1 0 _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ Z-adresa
Zdrojový kód UB-strom Zaddress Z(Tuple tuple) { Zaddress za = 0; int pos = 0, bit ; for (bit = 0; bit < maxbits(tuple); bit++) foreach attribute of tuple do if (attribute[bit] exists) { if (attribute[bit] is set) ZaddressSetBit(&za, pos); pos++; } return za; Atribut 1 Atribut 2 (25,18) Z-adresa Atribut 2 Atribut 1 1 0 0 1 0 _ _ _ _ _ _ _ _ _ _ 1 1 0 0 1 Bitové řetězce 1 1 0 1 0 0 _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ Z-adresa
Zdrojový kód UB-strom Zaddress Z(Tuple tuple) { Zaddress za = 0; int pos = 0, bit ; for (bit = 0; bit < maxbits(tuple); bit++) foreach attribute of tuple do if (attribute[bit] exists) { if (attribute[bit] is set) ZaddressSetBit(&za, pos); pos++; } return za; Atribut 1 Atribut 2 (25,18) Z-adresa Atribut 2 Atribut 1 1 0 0 1 0 _ _ _ _ _ _ _ _ _ _ 1 1 0 0 1 Bitové řetězce 1 1 0 1 0 0 1 _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ Z-adresa
Zdrojový kód UB-strom Zaddress Z(Tuple tuple) { Zaddress za = 0; int pos = 0, bit ; for (bit = 0; bit < maxbits(tuple); bit++) foreach attribute of tuple do if (attribute[bit] exists) { if (attribute[bit] is set) ZaddressSetBit(&za, pos); pos++; } return za; Atribut 1 Atribut 2 (25,18) Z-adresa Atribut 2 Atribut 1 1 0 0 1 0 _ _ _ _ _ _ _ _ _ _ 1 1 0 0 1 Bitové řetězce 1 1 0 1 0 0 1 0 _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ Z-adresa
Zdrojový kód UB-strom Zaddress Z(Tuple tuple) { Zaddress za = 0; int pos = 0, bit ; for (bit = 0; bit < maxbits(tuple); bit++) foreach attribute of tuple do if (attribute[bit] exists) { if (attribute[bit] is set) ZaddressSetBit(&za, pos); pos++; } return za; Atribut 1 Atribut 2 (25,18) Z-adresa Atribut 2 Atribut 1 1 0 0 1 0 _ _ _ _ _ _ _ _ _ _ 1 1 0 0 1 Bitové řetězce 1 1 0 1 0 0 1 0 0 _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ Z-adresa
Zdrojový kód UB-strom Zaddress Z(Tuple tuple) { Zaddress za = 0; int pos = 0, bit ; for (bit = 0; bit < maxbits(tuple); bit++) foreach attribute of tuple do if (attribute[bit] exists) { if (attribute[bit] is set) ZaddressSetBit(&za, pos); pos++; } return za; Atribut 1 Atribut 2 (25,18) Z-adresa Atribut 2 Atribut 1 1 0 0 1 0 _ _ _ _ _ _ _ _ _ _ 1 1 0 0 1 Bitové řetězce 1 1 0 1 0 0 1 0 0 1 _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ Z-adresa
Algoritmus vymazání bodu 1/2 Vstup: x: bod, který má být vymazán z UB-stromu Výstup: žádný x = Z(x) search [a : b] in the UB-Tree, such that a Ł x Ł b retrieve page(a : b) delete x from page(a : b) if count(a : b) < ½ C - e merge page(a : b) with the neighboring page(b + 1 : g) into page(a : g)
Algoritmus vymazání bodu 2/2 if count(a : g) > C choose d Î[a : g] with count(a : d) Ł ½ C - e and count(d + 1 : g) Ł ½ C - e split page(a : g) into page(a : d) and page(d + 1: g) end if
Algoritmus bodového dotazu Vstup: x: bod zadaný zaindexovanými atributy Výstup: x: bod se všemi atributy x = Z(x) find [a : b] in the UB-Tree, such that a Ł x Ł b retrieve page(a : b) into main memory search content of page(a : b) to find x
Vícerozměrný rozsahový dotaz SELECT * FROM table WHERE (A1 BETWEEN a1 AND b1) AND (A2 BETWEEN a2 AND b2) AND ..... (An BETWEEN an AND bn) N-rozměrný intervalový dotaz.
Algoritmus rozsahového dotazu Vstup: y,z: body definující dotazovací okno Z(y) < Z(z) Výstup: X: výsledná množina x = Z(y); w = Z(z); X = Ć repeat find [a: b] in the UB-Tree, such that a Ł x Ł b X = X Č {(x1, ... ,xd’) Î [a : b] | (x1, ... ,xd) Î [[ y, z]]} x = Z-address of the first point intersecting the query box with x > b until x > w
Ukázka rozsahového dotazu
rangeQuery(Tuple ql, Tuple qh) { Zaddress start = Z(ql); Zaddress cur = start; Zaddress end = Z(qh); Page page = {}; while (1) cur = getRegionSeparator(cur); page = getPage(cur); outputMatchingTuples(page, ql, qh); if ( cur >= end ) break; cur = getNextZAddress(cur, start, end); } Zdrojový kód UB-strom B*-strom lineární Z-prostor
rangeQuery(Tuple ql, Tuple qh) { Zaddress start = Z(ql); Zaddress cur = start; Zaddress end = Z(qh); Page page = {}; while (1) cur = getRegionSeparator(cur); page = getPage(cur); outputMatchingTuples(page, ql, qh); if ( cur >= end ) break; cur = getNextZAddress(cur, start, end); } Zdrojový kód UB-strom B*-strom lineární Z-prostor
rangeQuery(Tuple ql, Tuple qh) { Zaddress start = Z(ql); Zaddress cur = start; Zaddress end = Z(qh); Page page = {}; while (1) cur = getRegionSeparator(cur); page = getPage(cur); outputMatchingTuples(page, ql, qh); if ( cur >= end ) break; cur = getNextZAddress(cur, start, end); } Zdrojový kód UB-strom B*-strom lineární Z-prostor
rangeQuery(Tuple ql, Tuple qh) { Zaddress start = Z(ql); Zaddress cur = start; Zaddress end = Z(qh); Page page = {}; while (1) cur = getRegionSeparator(cur); page = getPage(cur); outputMatchingTuples(page, ql, qh); if ( cur >= end ) break; cur = getNextZAddress(cur, start, end); } Zdrojový kód UB-strom B*-strom lineární Z-prostor
rangeQuery(Tuple ql, Tuple qh) { Zaddress start = Z(ql); Zaddress cur = start; Zaddress end = Z(qh); Page page = {}; while (1) cur = getRegionSeparator(cur); page = getPage(cur); outputMatchingTuples(page, ql, qh); if ( cur >= end ) break; cur = getNextZAddress(cur, start, end); } Zdrojový kód UB-strom B*-strom lineární Z-prostor
rangeQuery(Tuple ql, Tuple qh) { Zaddress start = Z(ql); Zaddress cur = start; Zaddress end = Z(qh); Page page = {}; while (1) cur = getRegionSeparator(cur); page = getPage(cur); outputMatchingTuples(page, ql, qh); if ( cur >= end ) break; cur = getNextZAddress(cur, start, end); } Zdrojový kód UB-strom B*-strom lineární Z-prostor
rangeQuery(Tuple ql, Tuple qh) { Zaddress start = Z(ql); Zaddress cur = start; Zaddress end = Z(qh); Page page = {}; while (1) cur = getRegionSeparator(cur); page = getPage(cur); outputMatchingTuples(page, ql, qh); if ( cur >= end ) break; cur = getNextZAddress(cur, start, end); } Zdrojový kód UB-strom B*-strom lineární Z-prostor
rangeQuery(Tuple ql, Tuple qh) { Zaddress start = Z(ql); Zaddress cur = start; Zaddress end = Z(qh); Page page = {}; while (1) cur = getRegionSeparator(cur); page = getPage(cur); outputMatchingTuples(page, ql, qh); if ( cur >= end ) break; cur = getNextZAddress(cur, start, end); } Zdrojový kód UB-strom B*-strom lineární Z-prostor
rangeQuery(Tuple ql, Tuple qh) { Zaddress start = Z(ql); Zaddress cur = start; Zaddress end = Z(qh); Page page = {}; while (1) cur = getRegionSeparator(cur); page = getPage(cur); outputMatchingTuples(page, ql, qh); if ( cur >= end ) break; cur = getNextZAddress(cur, start, end); } Zdrojový kód UB-strom B*-strom lineární Z-prostor
rangeQuery(Tuple ql, Tuple qh) { Zaddress start = Z(ql); Zaddress cur = start; Zaddress end = Z(qh); Page page = {}; while (1) cur = getRegionSeparator(cur); page = getPage(cur); outputMatchingTuples(page, ql, qh); if ( cur >= end ) break; cur = getNextZAddress(cur, start, end); } Zdrojový kód UB-strom B*-strom lineární Z-prostor
rangeQuery(Tuple ql, Tuple qh) { Zaddress start = Z(ql); Zaddress cur = start; Zaddress end = Z(qh); Page page = {}; while (1) cur = getRegionSeparator(cur); page = getPage(cur); outputMatchingTuples(page, ql, qh); if ( cur >= end ) break; cur = getNextZAddress(cur, start, end); } Zdrojový kód UB-strom B*-strom lineární Z-prostor
rangeQuery(Tuple ql, Tuple qh) { Zaddress start = Z(ql); Zaddress cur = start; Zaddress end = Z(qh); Page page = {}; while (1) cur = getRegionSeparator(cur); page = getPage(cur); outputMatchingTuples(page, ql, qh); if ( cur >= end ) break; cur = getNextZAddress(cur, start, end); } Zdrojový kód UB-strom B*-strom lineární Z-prostor
rangeQuery(Tuple ql, Tuple qh) { Zaddress start = Z(ql); Zaddress cur = start; Zaddress end = Z(qh); Page page = {}; while (1) cur = getRegionSeparator(cur); page = getPage(cur); outputMatchingTuples(page, ql, qh); if ( cur >= end ) break; cur = getNextZAddress(cur, start, end); } Zdrojový kód UB-strom B*-strom lineární Z-prostor
rangeQuery(Tuple ql, Tuple qh) { Zaddress start = Z(ql); Zaddress cur = start; Zaddress end = Z(qh); Page page = {}; while (1) cur = getRegionSeparator(cur); page = getPage(cur); outputMatchingTuples(page, ql, qh); if ( cur >= end ) break; cur = getNextZAddress(cur, start, end); } Zdrojový kód UB-strom B*-strom lineární Z-prostor
rangeQuery(Tuple ql, Tuple qh) { Zaddress start = Z(ql); Zaddress cur = start; Zaddress end = Z(qh); Page page = {}; while (1) cur = getRegionSeparator(cur); page = getPage(cur); outputMatchingTuples(page, ql, qh); if ( cur >= end ) break; cur = getNextZAddress(cur, start, end); } Zdrojový kód UB-strom B*-strom lineární Z-prostor
rangeQuery(Tuple ql, Tuple qh) { Zaddress start = Z(ql); Zaddress cur = start; Zaddress end = Z(qh); Page page = {}; while (1) cur = getRegionSeparator(cur); page = getPage(cur); outputMatchingTuples(page, ql, qh); if ( cur >= end ) break; cur = getNextZAddress(cur, start, end); } Zdrojový kód UB-strom B*-strom lineární Z-prostor
rangeQuery(Tuple ql, Tuple qh) { Zaddress start = Z(ql); Zaddress cur = start; Zaddress end = Z(qh); Page page = {}; while (1) cur = getRegionSeparator(cur); page = getPage(cur); outputMatchingTuples(page, ql, qh); if ( cur >= end ) break; cur = getNextZAddress(cur, start, end); } Zdrojový kód UB-strom B*-strom lineární Z-prostor
rangeQuery(Tuple ql, Tuple qh) { Zaddress start = Z(ql); Zaddress cur = start; Zaddress end = Z(qh); Page page = {}; while (1) cur = getRegionSeparator(cur); page = getPage(cur); outputMatchingTuples(page, ql, qh); if ( cur >= end ) break; cur = getNextZAddress(cur, start, end); } Zdrojový kód UB-strom B*-strom lineární Z-prostor
Práce s obecnými objekty 1/3
Práce s obecnými objekty 2/3
Práce s obecnými objekty 3/3 pro objekt o je vytvořen ohraničující obdélník bb(o) pro objekt o jsou uloženy identifikátory Id(o) pro každý region, který o protíná objekt sám je uložen mimo UB-strom o může protínat pouze regiony, které jsou protínány bb(o)
Vložení obecného objektu 1. Výpočet bb(o) 2. for all regions R which intersect bb(o) do if R intersects o then insert Id(o) into R // může dojít k rozštěpení R ...
Vyhledání objektů v zadaném okně 1. Nalezneme všechny regiony a získáme korespondující stránky dotazovacího okna q (stránky obsahují identifikátory Id(o) pro všechny objekty o, které protínají tyto regiony). 2. Pro všechny Id(o) zjišťujeme, zda o protíná q. Další algoritmy: * dotazy na body v okolí bodu * efektivnější algoritmus výběru stránek a jejich kešování při vykonávání rozsahového dotazu, tzv. Tetris algoritmus
Složitosti algoritmů bodový dotaz: O(logk N), kde N je počet n-tic, k = 1/2M, M je kapacita stránky rozsahový dotaz: r*O(logk N), kde r je počet regionů protínajících dotazovací okno vložení bodu (n-tice): O(logk N) vložení objektu: r*O(logk N), kde r je počet regionů protínajících bb(o) vymazání bodu: O(logk N) vymazání objektu: r*O(logk N) Vložení n-tice požaduje vyhledání bodu ke zjištění regionu a stránky. Jestliže je rozdělení spuštěno vložením, je nutné vyhledat cestu v UB-stromu, ale nedojde ke zvýšení řádu ceny. Pro mazání platí to samé.
Výhody UB-stromů Garance logaritmické časové složitosti v nejhorším případě pro vkládání, mazání a bodové dotazy Shlukování n-tic na diskové stránky při jejich prostorové blízkosti Dobré průměrné využití paměti Efektivní rozsahové dotazy Porovnání: R-strom - negarantuje logaritmickou složitost, neposkytuje dobré průměrné využití paměti 4-strom - strom může být nevyvažený Je důležité poznamenat, že pokud má být rozštěpena stránka, je rozdělen pouze jediný Z-region, výsledkem je pouze jeden update a jeden zápis do stránky listu B-stromu (plus další možné rozdělení na vyšších úrovních B-stromu). Toto je hlavní rozdíl od ostatních vícerozměrných přístupových metod jako R-stromy nebo Grid-Files. Existuje prototypová implementace (knihovna pro TransBase, Oracle, DB2) - Volker Markl.
Odkazy http://mistral.in.tum.de R. Bayer. The Universal B-Tree for multidimensional indexing, http://mistral.in.tum.de/results/publications/ TUMI9637.pdf V. Markl. MISTRAL: Processing Relational Queries using a Multidimensional Access Technique, http://mistral.in.tum.de/results/publications/Mar99.pdf http://www.cs.vsb.cz/~dis http://www.cs.vsb.cz/kratky/ub-tree