Stáhnout prezentaci
Prezentace se nahrává, počkejte prosím
ZveřejnilGabriela Horáková
1
Univerzální kvantifikátory v relačních databázích - algoritmy Jan BUREŠ Dung NGUYEN TIEN 2007
2
Obsah Úvod terminologie, univerzální kvantifkátory a jejich použití Algoritmy klasifikace dat přehled zhodnocení Množinový pohled Literatura
3
Terminologie Univerzální kvantifikátor univerzálním kvantifikátorem rozumíme kvantifikátor používaný v relačních kalkulech univerzální kvantifikátor aplikovaný na proměnnou x formule f nám říká, že daná formule je pravdivá pro všechny hodnoty x zápis: x : f(x)
4
Použití V relačních databázích nachází použití v mnoha moderních aplikacích analytické operace (OLAP) data mining „vnořené“ SELECTy = univerzální kvantifkátor
5
Implementace V praxi bývá univerzální kvantifikátor implementován pomocí operátoru dělení ( ) relační algebry
6
Univerzální příklad V průběhu referátu budeme používat následující jednoduchý příklad ze života tabulka předmět tabulka zápis Tabulka předmět neobsahuje všechny předměty – je pouze jejich podmnožinou (např. množina předmětů určitého vyučujícího) zápis student_idpředmět_id AlbertAnalýza AlbertPřekladače BoženaAnalýza BoženaDatabáze BoženaGrafika BoženaPřekladače CtiradAnalýza CtiradGrafika CtiradPřekladače (a) Dělenec předmět předmět_id Analýza Databáze Překladače (b) Dělitel výsledek student_id Božena (c) Podíl
7
Operátor dělení „Kteří studenti si zapsali všechny předměty?“ Z tabulek je jasné, že odpovědí na dotaz je Božena Operátor dělení vezme dvě tabulky – dělence a dělitele a vygeneruje tabulku podíl Aby se záznam mohl objevit v tabulce podíl musí se v dělenci vyskytovat spárovaný se všemi hodnotami z dělitele
8
Cíle referátu Tento referát se zaměří především na algoritmy implementace operátoru dělení přehled těchto algoritmů jejich srovnání s ohledem na vstupní data množinový pohled
9
„Nejlepší“ algoritmus Každý autor o svém algoritmu pro univerzální kvantifikátory tvrdí, že je nejlepší Který je skutečně nejlepší? Žádný! Každý se hodí pro jiná data Rychlost algoritmů závisí na stavu vstupních dat
10
Klasifikace dat Pro přehlednost a snadné srovnání algoritmů budeme brát v potaz několik různých stavů vstupních dat – „tříd“ Na základě stavu dělitele a dělence (v našem příkladu tabulek předmět a zápis)
11
Setřídění X Sdružení Sdružení (grouping) = GROUP BY Setřídění = ORDER Většině algortimů stačí požadavek sdružených dat, nepotřebují data setříděná Setřídění je speciální případ sdružení (grouping) Sdružení je tedy silnějším předpokladem
12
Třídy Ne všechny kombinace stavů tabulek jsou nám „k něčemu“ Některé kombinace nemají žádné speciální vlastnosti využitelné některým z námi probíraných algoritmů Proto uvažujeme pouze 4 třídy dat
13
Klasifikace dat – třída 0 Žádné sloupce nejsou sdružené Neuspořádaná, náhodná data Nejzákladnější, obsahuje všechny další důležité třídy (2, 5, 10) zápis student_idpředmět_id BoženaDatabáze CtiradAnalýza CtiradGrafika AlbertPřekladače BoženaGrafika CtiradPřekladače AlbertAnalýza BoženaAnalýza BoženaPřekladače nesdruženo předmět předmět_id Databáze Překladače Analýza nesdruženo
14
Klasifikace dat – třída 2 Tabulka zápis má data sdružena podle sloupce předmět_id Obecně – data sdružená podle sloupce hodnot, na jejichž základě se dělí (dělenec) Neobsahuje žádné další důležité třídy předmět předmět_id Databáze Překladače Analýza nesdruženo zápis student_idpředmět_id AlbertPřekladače CtiradPřekladače BoženaPřekladače BoženaDatabáze CtiradGrafika BoženaGrafika CtiradAnalýza BoženaAnalýza AlbertAnalýza nesdruženosdruženo
15
Klasifikace dat – třída 5 Tabulka zápis má data sdružena podle sloupce student_id Obecně – data sdružena podle sloupce, který zbyde po dělení (podíl) Obsahuje důležitou třídu 10 předmět předmět_id Databáze Překladače Analýza nesdruženo zápis student_idpředmět_id AlbertAnalýza AlbertPřekladače BoženaPřekladače BoženaGrafika BoženaDatabáze BoženaAnalýza CtiradGrafika CtiradPřekladače CtiradAnalýza sdruženonesdruženo
16
Klasifikace dat – třída 10 Tabulka zápis má data sdružena podle sloupce student_id Poté podle sloupce předmět_id Ve stejném pořadí je sdružena i tabulka předmět podle předmět_id předmět předmět_id Analýza Databáze Překladače Sdruženo zápis student_idpředmět_id AlbertAnalýza AlbertPřekladače BoženaAnalýza BoženaDatabáze BoženaGrafika BoženaPřekladače CtiradAnalýza CtiradGrafika CtiradPřekladače sdruženo
17
Složitost algoritmů Při analýze složitosti algoritmů je vstupem Tabulka dělenec (dividend) S(Q, D) Tabulka dělitel (divisor) T(D) Q-množina odpovídá naší množině jmen studentů D-množina odpovídá naší množině předmětů
18
Univerzální kvantifikátor v SQL Užití „NOT EXISTS“ SELECT DISTINCT student_id FROM zapis AS z1 WHERE NOT EXISTS ( SELECT * FROM predmet AS p WHERE NOT EXISTS ( SELECT * FROM zapis AS z2 WHERE z2.student_id = z1.student_id AND z2.predmet_id = p.predmet_id)) Co vyjadřuje select?
19
Univerzální kvantifikátor v SQL Předchozí select hledá každého studenta, pro kterého neexistuje žádný předmět, který by nenavštěvoval Užití kvantifikátoru „FOR ALL“ by bylo intuitivnější, ale není ve standardu
20
Univerzální kvantifikátor v SQL Každý dotaz s univerzálním kvatifikátorem lze nahradit dotazem, který používá agregační funkce SELECT student_id FROM zapis GROUP BY student_id HAVINGCOUNT(DISTINCT predmet_id) = ( SELECTCOUNT(DISTINCT predmet_id) FROMpredmet)
21
Skalární algoritmy Využívají přímou shodu řádků mezi tabulkami Pro přesnost ponecháme názvy v angličtině Nested-loops division (NLD) Merge-sort division (MSD) Merge-group division (MGD) Classic hash-division (HD) Transposed hash-division (HDT) Hash-division for quotient groups (HDQ) Transposed hash-division for quotient groups (HDTQ)
22
Nested-loops division (NLD) Nejnaivnější algoritmus, ale protože nemá speciální požadavky na data, lze jej vždy použít
23
Nested-loops division (NLD) Používá 2 sady datových struktur Jednu pro uchování hodnot dělitele (předměty), tabulka seen_divisors Druhou pro hodnoty kandidátů kvocientu, tabulka seen_quotients
24
Nested-loops division (NLD) Algoritmus Naplníme tabulku seen_divisors(předměty) Pak zkoumáme dělenec Pro každý řádek zjistíme, jestli je aktuální kvocient již v tabulce seen_quotients(jména studentů) Pokud ne, přidáme do tabulky a pokračujeme iterativně a najdeme řádky se shodným kvocientem vnějšího cyklu Pro každý takový řádek zkontrolujeme, jestli je jeho hodnota dělitele již v tabulce seen_divisors Pokud ano, označíme tuto hodnotu Pokud na konci jsou všechny jeho dělitelé označeny, vypíšeme aktuální kvocient(jméno studenta)
25
Nested-loops division (NLD) Může být velmi neefektivní Pro každý řádek dělence může projít až všechny řádky dělitele Typická složitost O(|S| 2 )
26
Merge-sort division Předpoklady Dělitel T je vytříděný Dělenec S je seskupený dle Q a každá skupina je uvnitř setříděná dle D jako T
27
Merge-sort division Algoritmus Předpoklad vzestupného třídění Začneme prvním řádkem dělitele a dělence Jestli dělitel je roven hodnotě D aktuálního řádku dělence, postoupíme na další řádek v obou tabulkách Jestli D < dělitel, postoupíme na další řádek skupiny Jestli už nejsou žádné řádky v kvocient skupině, ale aspoň jedna v děliteli, postoupíme na další skupinu Jestli už nejsou žádné řádky v děliteli, našli jsme kvocient
28
Merge-sort division Složitost O(|S| + |Q||T|)
29
Merge-group division Zbobecněním MSD Oba vstupy seskupeny,nemusí být setříděné
30
Merge-group division Lze bezpečně přeskočit kvociet kandidáta, pokud aktuální hodnota Q > aktuální řádek dělitele, pokud je třídění vzestupné Jelikož se setřídění nevyžaduje, nelze přeskočit na další skupinu při neshodě hodnot, jako při MSD
31
Merge-group division Složitost O(|S| + |Q||T|)
32
Classic hash-division
33
2 hašovací tabulky pro dělitele a kvocient Podílová hašovací tabulka uchovává kandidáta a má bitmapu ke každému kandidátovi s jedním bitem pro každého dělitele
34
Classic hash-division Algoritmus Sestaví hašovací tabulku dělitele Každý řádek s unikátním číslem index dělitele Sestaví podílovou hašovací tabulku a doplní příslušné bity Vypíše všechny podílové kandidáty se samými jedničkami
35
Classic hash-division Složitost O(|S| + |T|)
36
Transposed hash-division Mírná variace HD
37
Transposed hash-division Uchovává bitmapu společně s řádkem v hašovací tabulce dělitele, na rozdíl od HD
38
Hash-division for quotient groups
39
Jde o optimalizaci HD Dělenec je seskupován dle Q, tím tedy nepotřebujeme podílovou hašovací tabulku
40
Transposed hash-division for quotient groups
41
Agregační algoritmy Nepracují přímo s konkrétními hodnotami, místo nich pracují s počty řádek Spočítají počet řádek náležejících každému „podílovému kandidátu“ (student v našem příkladu) a ten porovnávají s počtem řádek v děliteli (tabulka předmět v našem příkladu)
42
Agregační algoritmy Nevýhody agregačních algoritmů: nedokáží se vypořádat s duplicitními řádky (až na výjimky) nedokáží se vypořádat s „NULL“ hodnotami potřebují zajištěnou referenční integritu (v našem příkladě odstraněny řádky s předmět_id = Grafika)
43
Nested-Loops Counting Division (NLCD) „Nejnaivnější“ z agregačních algoritmů Nemá žádné požadavky na předzpracování dat (třída 0) Stejně jako ostatní agregační algoritmy se nevypořádá s duplicitními řádky, nulovými řádky a potřebuje zajištěnou referenční integritu Vyžaduje mnoho průchodů tabulkou
44
NLCD – princip Používá dva cykly (nested loops) Na počátku projde dělitele a spočítá řádky Vnější cyklus postupně bere dělence řádek po řádku – pokud najde takový řádek, jehož podílového kandidáta ještě nemá ve své tabulce projitých kandidátů, přidá ho tam, nastaví počitadlo na 1 a vstoupí do vnitřního cyklu Vnitřní cyklus projde celá data a najde všechny řádky s podílovým kandidátem, který se zrovna ověřuje – pokaždé zvedne počitadlo o 1. Pokud se počitadlo rovná počtu řádků dělitele, přidá podílového kandidáta do výstupu, poté se vrátí do vnějšího cyklu Počet řádků se drží v globální proměnné
45
NLCD - příklad s1 = s2 = zapis while predmet.next() do dpocet++; while s1.next() do if s1.student_id not in podilhashtable then begin while s2.next() do if s1.student_id == s2.student_id then begin spocet++; if spocet == dpocet begin output s1.student_id; break; end; spocet = 1; insert s1.student_id into podilhashtable; end;
46
NLCD – shrnutí Nemá žádné požadavky na data, je proto univerzální Časová složitost je v nejhorším případe O(|S|2 + |T|), typicky pak O(|S|2), tedy stejná, jako u NLD Paměťová náročnost je menší než u NLD – je potřeba si držet pouze projité podílové kandidáty, tedy O(|Q|), což je v nejhorším případě O(|S|)
47
Merge-Count Division (MCD) Je mnohem rychlejší než NLCD, ale za cenu omezení jen na určitá data Potřebuje data sdružená podle podílových kandidátů (třída 5) Stačí mu jeden průchod tabulkou
48
MCD - princip Na počátku opět projde tabulku dělitele a spočítá její řádky Prochází postupně tabulku dělence – vždy, když narazí na nového podílového kandidáta, nastaví počitadlo na 1, při vstupu na každý další řádek jej pak o 1 zvýší – pokud se počitadlo rovná počtu řádku v děliteli, podílového kandidáta dá do výsledku
49
MCD - příklad dpocet = 0 while not predmet.isEmpty() do begin dpocet++; předmět.next(); end; if not zapis.isEmpty() then begin zapis.next(); podilovy_kandidat = zapis.student_id; end; while not zapis.isEmpty() do begin spocet = 0; while not zapis.isEmpty() and zapis.student_id == podilovy_kandidat do begin spocet++; zapis.next(); end; if spocet == dpocet then output podilovy_kandidat; if not zapis.isEmpty() podilovy_kandidat = zapis.student_id; end;
50
MCD - shrnutí Časová složitost je v nejhorším případě O(|S| + |T|) – jeden průchod každou z tabulek V průměrném případě pak O(|S|) Náročnost na paměť je velmi nízká, potřebujeme pouze dvě proměnné na počítání řádků Paměťová složitost je tedy O(1)
51
Hash-Division for Divisor Groups (HDD) Jak název napovídá, potřebuje data v dělenci sdružená podle sloupce obsahujícího hodnoty z dělitele (třída 2) Jedná se o variaci na „obyčejný“ hash- division algoritmus „Blokující“ – žádný výstup v průběhu, výstup je generován až po projití celé tabulky
52
HDD - princip Prochází dělence a pro každý řádek se podívá, jestli je podílový kandidát již v podílové hašovací tabulce – pokud ne, vloží jej a nastaví počítadlo na 1, pokud ano, zvýší počítadlo o 1 Navíc počítá kolik se již vystřídalo různých hodnot ve sloupci obsahujícím hodnoty z dělitele Nakonec vrátí všechny podílové kandidáty z podílové hašovací tabulky, jejichž počitadlo se rovná globálnímu počítadlu
53
HDD - příklad zapis.next(); delitel = zapis.predmet_id; dpocet = 1; while zapis.isEmpty() do begin if zapis.student_id not in podilhashtable insert (zapis.student_id, 0) into podilhashtable podilhashtable(zapis.student_id).value++; zapis.next(); if delitel != zapis.predmet_id then dpocet++; end; podilhashtable.first(); while podilhashtable.isEmpty() do begin if podilhashtable.value == dpocet output podilhashtable.student_id; podilhashtable.next(); end;
54
HDD - shrnutí Časová složitost je v nejhorším případě O(|S| + |T|), v průměrném tedy O(|S|) Paměťová složitost je O(|Q|), tedy v nejhorším i průměrném případě O(|S|)
55
Transposed Hash-Division for Divisor Groups (HDTD) Je odvozen od Transposed Hash- Division algoritmu Potřebuje data v dělenci sdružená podle sloupce obsahujícího hodnoty z dělitele (třída 2) „Blokující“ – žádný výstup v průběhu, výstup je generován až po projití celé tabulky
56
HDTD - princip Princip algoritmu je totožný s předchozím algoritmem, pouze hodnoty se nedrží přímo v podílové hašovací tabulce, ale stranou ve vektoru – v podílové hašovací tabulce se drží index daného podílového kandidáta v tomto vektoru
57
HDTD - shrnutí Časová složitost je v nejhorším případě O(|S| + |T|), v průměrném tedy O(|S|) Paměťová složitost je O(|Q|), tedy v nejhorším i průměrném případě O(|S|)
58
Stream-Join Division (SJD) Není „opravdovým“ agregačním algoritmem – má k nim ale blízko Požaduje referenční integritu Není schopen se vypořádat s duplicitami v děliteli Duplicity v dělenci mu nevadí Vyžaduje data třídy 5 (sdružena podle sloupce obsahujícího hodnoty z dělitele)
59
SJD - princip Používá jednu hašovací tabulku podílových kandidátů, u každého mu stačí jeden bit Na začátku vezme první skupinu (podle dělitele, tedy podle předmětu v našem příkladě) a všechny podílové kandidáty (studenty) umístí do hašovací tabulky a nastaví jim bit na 0 Poté vždy pro každou další skupinu prochází řádky a nastaví bit na 1 všem podílovým kandidátům, které se v ní vyskytují a zároveň se vyskytují i v hašovací tabulce Při přechodu na další skupinu jsou smazány všechny položky z hašovací tabulky, jejichž bit je nastaven na 0 Všechny bity jsou nastaveny na 0 Na konci se porovná čítač skupin s počtem řádků v děliteli – pokud odpovídá, všechny položky, které zbyly v hašovací tabulce a mají bit nastaven na 1 jsou výsledkem
60
SJD - příklad zapis.next(); dpocet1 = 1; delitel = zapis.predmet_id; while not zapis.isEmpty() and delitel == zapis.predmet_id do begin insert (zapis.student_id, 0) into podilhashtable; zapis.next(); end; while not zapis.isEmpty() do begin if delitel != zapis.predmet_id then begin dpocet1++; podilhashtable.first(); while not podilhashtable.isEmpty() do begin if podilhashtable.value == 0 thenpodilhashtable.delete(); elsepodilhashtable.value = 0; podilhashtable.next(); end; podilhashtable(zapis.student_id).value = 1; zapis.next(); end; dpocet2 = 0; while not predmet.isEmpty() do begin dpocet2++; předmět.next(); end; podilhashtable.first(); if dpocet1 == dpocet2 then while not podilhashtable.isEmpty() do begin if podilhashtable.value == 1 then output podilhashtable.student_id; podilhashtable.next(); end;
61
SJD - shrnutí Časová složitost je v nejhorším případě O(|S| + |T|), v průměrném tedy O(|S|) Paměťové nároky se velmi liší, závisí na počtu podílových kandidátů v první skupině – v nejhorším i průměrném případě se tedy rovnají O(|S|)
62
Zhodnocení algoritmů Algoritmus dělení Typ algoritmu Třída dat Dělenec (S) Dělitel (T) Složitost ČasováPaměťová QDnejhoršíprůměrnýnejhoršíprůměrný NLCDagregační 0NNN |S| 2 + |T||S| 2 |S| NLDskalární |S| 2 + |T||S| 2 |S| + |T||S| HDskalární |S| + |T||S||S||T| HDTskalární |S| + |T||S||S||T| HDDagregační 2NGN |S| + |T||S| HDTDagregační |S| + |T||S| SJDagregační |S| + |T||S| MCDagregační 5GNN |S| + |T||S|11 HDQskalární |S| + |T||S||T|1 HDTQskalární |S| + |T||S||T|1 MGDskalární 10G1G2 |S||T| |T|1 MSDskalární S2 |S||T| 11
63
Množinový pohled „Kteří studenti si zapsali všechny předměty?“ „Najdi studenty, u kterých množina zapsaných předmětů obsahuje jako podmnožinu množinu všech předmětů.“
64
Datová reprezentace množin Klasické relační databáze používají 1NF Pro ukládání množin jsou vhodnější struktury – jednou z nich je možnost do jednoho atributu místo jedné hodnoty uložit množinu hodnot (z nějaké dané domény)
65
Podmnožinové spojení Podmnožinové spojení je operátor nad hnízděnými tabulkami Definovaný nad dvěma relacemi R(a,b) a S(c,d) najde všechny dvojice (a,d), kde pro dané b náležející k a obsahuje jako podmnožinu c
66
Podmnožinové dělení Podmnožinové spojení nemá definované chování nad nehnízděnými tabulkami (1NF) Řeší to operátor podmnožinového dělení
67
Podmnožinové dělení Tento operátor je sjednocením dílčích operátorů dělení Pro každé unikátní d z S(c,d) vezmu množinu všech k němu náležejících c a vydělím s ní R(a,b)
68
Srovnání
69
Literatura Algorithms and Applications for Universal Quantification in Relational Databases (2002) Ralf Rantzau, Leonard D. Shapiro, Bernhard Mitschang, Quan Wang
Podobné prezentace
© 2024 SlidePlayer.cz Inc.
All rights reserved.