Prezentace se nahrává, počkejte prosím

Prezentace se nahrává, počkejte prosím

Stromy a hierarchické struktury v SQL 30.11.2005 Mária Szabó, Jirka Zouhar, Gergely Jakab.

Podobné prezentace


Prezentace na téma: "Stromy a hierarchické struktury v SQL 30.11.2005 Mária Szabó, Jirka Zouhar, Gergely Jakab."— Transkript prezentace:

1 Stromy a hierarchické struktury v SQL 30.11.2005 Mária Szabó, Jirka Zouhar, Gergely Jakab

2 Using the Node Type to Solve Problems with Hierarchies in DB2 Universal Database Mária Szabó 30.11.2005

3  Základní pojmy  Úvod do problematiky  Koncept řešení  Node type  Výhody  Příklady Node Type & Hierarchies in DB2

4 ● Hiearchie ● Relační Db ● Node Type Pojmy

5 Node Type & Hierarchies in DB2 ● Před 30 lety – hierarchical db ● Svázánost se db strukturou ● Ukazatel – pointer ● Nákladné chyby ● Vícenásobné použití pro stejná data Problematika

6 Node Type & Hierarchies in DB2 Průměr účetní bilance pro každý region i odvětví 10 největších klientů  Definovat více hierarchií  Synchronizace dat

7 Node Type & Hierarchies in DB2 Pre-processing dat Myšlenka typu UZEL Série čísel Hladina – Level Indexování jako v SQL Uzel & Hierarchie

8 Node Type & Hierarchies in DB2 CREATE TABLE employee ( Employee_Id Integer, Manager_Id Integer, Last_Name varchar(30)... PRIMARY KEY(Employee_Id), FOREIGN KEY (Manager_Id) REFERENCES employee(Employee_Id); Kolik zaměstnanců pracuje pro jistého managera? SELECT COUNT (*) FROM employee emp, employee manager WHERE emp.Manager_Id = manager.Employee_Id AND manager.Last_Name = ‘Roy’; Pro každého zaměstnance zjistit počet podřízených !?!

9 Node Type & Hierarchies in DB2 ● Vícenásobné levely v managmentu ● SQL příkaz pro každý manager pro každý level ● Víckrát vnořovat Problém CREATE TABLE employee2 ( Employee_Id Node, Last_Name varchar(30),... PRIMARY KEY(Employee_Id);

10 Node Type & Hierarchies in DB2 1| |Joe| 2|1|Joe2|... 8|2|Joe8|... 14|3|Joe14| 1.0|Joe| 1.2|Joe2|... 1.2.8|Joe8|... 1.3.14|Joe14| ---------------------------- NULL na místě managera  šéf

11 Node Type & Hierarchies in DB2 ● Kolik zaměstnanců pracuje pod specifikovaným managerom? 1.Přímé potomky 2.Rekurzie dokud jsme neprošli všechny lidi 3.Rekurzivní dotaz nebo procedura WITH RPL (employee_Id, Manager_Id, Last_Name) AS (SELECT ROOT.employee_Id, ROOT.Manager_Id, ROOT.Last_Name FROM employee ROOT WHERE ROOT.employee_Id = 1 UNION ALL SELECT CHILD.EMployee_Id, CHILD.Manager_Id, CHILD.Last_Name FORM RPL PARENT, employee CHILD WHERE PARENT.Employee_Id = CHILD.Manager_Id ) SELECT COUNT(*) -1 FROM RPL; Pro EMPLOYEE table:

12 Node Type & Hierarchies in DB2 ● Kolik zaměstnanců pracuje pod špecifikovaným mangerom? SELECT COUNT(*) FROM Employee2 WHERE Employee_ID > NodeInput(‘1.2’) AND EMPLOYEE_ID < NodeInput(‘1.3’); Pro EMPLOYEE2 table: 1.3 > 1.2.8 > 1.2 uzly, které padají pod spec. managerom

13 Node Type & Hierarchies in DB2 ÚroveňPočetRozdíl 261.0 3421.8 42588.4 5155441 6933037.75 Test Každý manager 6 přímých potomků Lidi úplně na spodku nejsou managery pro 9331 řádků 37 násobné zrychlení tradiční přístup exponenciální char. uzlový přístup lineární charakteristika rozdíl se zvětšuje #levelu

14 Node Type & Hierarchies in DB2 Ancestors(Node) GetMember(Node,intege r) GetParent(Node) Graft(Node,Node,Node)Increment(Node)Increment(Node,integer) Graft(Node,Node,Node) IsChild(Node,Node) IsDescendant(Node,Nod e) IsParent(Node.Node) Length(Node)NewLevel(Node) NodeInput(varchar(180))NodeOutput(Node) Implementace typu UZEL - NODE CREATE DISTINCT TYPE Node AS varchar(64) FOR BIT DATA WITH COMPARISONS;

15 Node Type & Hierarchies in DB2 Indexování a SQL dotazy indexování typu uzel umístnit do WHERE klauzuli možnost i bez indexování  scan table SELECT * FROM employee2 WHERE isDescendant(employee_Id, NodeInput(‘1.7.43’)) ORDER BY employee_Id Desc; Příklad vrátí všechny potomky uzlu 1.7.43

16 Node Type & Hierarchies in DB2 Příklad vrátí všechny potomky uzlu 1.7.43 SELECT * FROM employee2 WHERE employee_Id > NodeInput(‘1.7.43’) AND employee_Id < NodeInput(‘1.7.44’) ORDER BY employee_Id Desc; Příklad vrátí pouze přímé potomky uzlu 1.7.43 SELECT * FROM employee2 WHERE employee_Id > NodeInput(‘1.7.43’) AND employee_Id < NodeInput(‘1.7.44’) AND Length(employee_id) = 4 ORDER BY employee_Id Desc;

17 Node Type & Hierarchies in DB2 !Občas je zapotřeby přidat funkce pro zachování použitelnosti indexu! SELECT * FROM employee2 WHERE isAncestor(employee_Id, NodeInput(‘1.7.43.256.1537’)) ORDER BY employee_Id Desc; 1.7.43.256, 1.7.43, 1.7, 1.0 SELECT * FROM Employee2 WHERE Employee_Id IN ( SELECT x.col1 FROM TABLE(Ancestors(NodeInput(‘1.7.43.256.1537’))) AS x ) ORDER BY employee_Id Desc;

18 Node Type & Hierarchies in DB2 Hlavní výnos Obrovské tabulky  rýchlá odezva Rozumné dotazy  nezávislost na # požadavků

19 Děkuji Mária Szabó 30.11.2005

20 Detaily hierarchii v DB2 30.11.2005 Jirka Zouhar

21 Použití ● Ve složitějších případech je třeba oddělit hierarchii od dat ● Lze použít i více hierarchií ● Příklady: – Skladová evidence zásob – Hierarchické systémy zásad – Klasifikace objektů

22 Hierarchie zásad ● CREATE TABLE Policies( PolicyNumberNode, Descriptionvarchar(50)); ● CREATE TABLE Objects( Namevarchar(50), PolicyNumberNode); ● CREATE TABLE Safe_places( LocationNode, PolicyNumberNode, Descriptionvarchar(75), Administratorvarchar(30));

23 Hierarchie zásad ● Jaké objekty mají „malé“ zabezpečení? ● Jak zabezpečený je daný objekt? ● Mají všechny zóny korektní zabezpečení? ● Nejsou objekty v špatných zónách? ● SELECT * FROM Objects, Places WHERE Places.policyNumber NOT IN Ancestors(Objects.policyNumber)

24 Skladová evidence ● CREATE TABLE Parts ( PartNumberinteger, Namevarchar(30), Pricemoney); ● CREATE TABLE Components ( ComponentIdNode, Sequenceinteger, Quantityinteger, Namevarchar(30), PartNumberinteger);

25 Klasifikace Objektů ● CREATE TABLE materials ( – Namevarchar(30), – TypeNode); ● CREATE TABLE parts( – Namevarchar(30), – Typenode, – ComponentIdnode, – Priceinteger, – Providervarchar(30), – PartNumberingeter, – Descriptioninteger);

26 Klasifikace objektů 1Materiál 1.1.1mahagon 1.2železo1.1dřevo1.3kůže

27 Klasifikace objektů ● Najdi všechny součástky z mahagonu s cenou menší padesáti. ● SELECT name,desc,price FROM parts WHERE isDescendant(type, NodeInput( SELECT type FROM materials WHERE name='mahagon')) AND price < 50;

28 Funkce pro práci s Node Type ● Node nodeInput (varchar) Převede varchar na Node Type. ● Varchar nodeOutput (node) Převede Node Type na Varchar V dalším bude pro zjednodušení používán místo nodeInput ('1.3.5') zjednodušený zápis 1.3.5

29 Funkce pro práci s Node Type ● Node[] Ancestors (node) Vrátí seznam předků: Ancestors(1.25.3) = {1.25,1} ● Integer GetMember (Node, Integer) Vrátí číslo větve na dané úrovni: GetMember(1.3.5.4,2) = 3 ● Node getParent (node) Vrátí otce zadaného: getParent(1.5.4) = 1.5

30 Funkce pro práci s Node Type ● Node Increment (node) Vrátí další node v řadě: Incerment (1.2.22) = 1.2.23 ● Node Increment (node, integer) Vrátí další node v řadě na dané úrovni: Increment (1.2.22, 2) = 1.3 ● Node newLevel (node) Vrátí nový node o úroveň níž: newLevel (1.2) = 1.2.1

31 Funkce pro práci s Node Type ● Integer isAncestor (node1, node2) Testuje, zda je node2 v podstromu node1: isAncestor (1.2, 1.2.3.55) = 1 isAncestor (1.3, 1.2.4) = 0 ● Integer isDescendant(node,node) Opak isAncestor: isDescendant (node1, node2) = isAncestor (node2, node1)

32 Funkce pro práci s Node Type ● Integer isChild (node1, node2) Testuje, zda je node2 synem node1: isChild (1.2, 1.2.3) = 1 isChild (1.2, 1.2.3.5) = 0 ● Integer isParent (node, node) Opak isChild ● Integer length(node) Zjistí úroveň node ve stromu: length (1.2.3.5) = 4

33 Funkce pro práci s Node Type ● Node graft(node,node,node) Přesune větev danou třetím parametrem jako podstrom druhého parametru, první je otec přemísťovaného stromu. UPDATE Parts SET Part_num = Graft( 1.2, 1.5.6, Part_num) WHERE Part_num > 1.2.18 AND Part_num < 1.2.19

34 Funkce pro práci s Node Type ● Graft (1.1.3, 1.4, 1.1.3.2) = 1.4.2 1.1.3.2 1 1.1.3 1.11.4 1.4.1 1.1.31.4.21.4.1 1.41.1 1

35 Zdroje ● http://www3.software.ibm.com/ http://www3.software.ibm.com/ ibmdl/pub/software/dw/dm/db2/0302roy/ 0302roy.pdf ● http://www3.software.ibm.com/ http://www3.software.ibm.com/ ibmdl/pub/software/dw/dm/db2/0302roy/ DB2Node.zip

36 Hnízděné intervaly 30.11.2005 Gergely Jakab Nested intervals

37 Obsah ● Úvod ● Materializovaná cesta ● Vnořené množiny – vylepšení ● Vnořené intervaly – Základní myšlenka – Mapovaní – Normalizace – Funkce – Příklady: Test struktury

38 Úvod ● tranzitivní závislosti v relační databázi (hierarchické struktury) ● 4 dobře známé metody z nichž 2 prozkoumáme – materializovaná cesta – vnořené množiny ● Vadim Tropashko vymyslel smíšeninu těchto dvou metod (vnořené intervaly) ● implementace a příklady na Oracle

39 Skok zpátky : materializovaná cesta ● každý záznam obsahuje absolutní cestu k uzlu ● cesta = čísla uzlů od kořene oddělené separátorem ● jistá podobnost k absolutním cestám na UNIXu ● kompaktnější verze místo primárního klíče uzlů staví cestu z pořadového čísla uzlu mezi sourozenci

40 Dotazy u materializované cesty standardní dotazy s „LIKE“ : efektivní na podřízené NEefektivní na nadřízené chytré dotazování pro nadřízené: pomoci řetězcové funkce, která vrátí množinu cest všech nadřízených f('1.2.1.1') = ('1.2.1', '1.2', '1') …WHERE super.path in f(this.path)

41 Vnořené množiny ● uchovává globální pozici uzlu ● pozice uzlu = 2 celé čísla definující interval [left, right], který obsahuje všechny potomky ● uzel p je předkem uzlu c právě když : p.left <= c.left <= c.right <= p.right ● nevýhody : – dotazy na nadřízené (hledání intervalů obsahující daný bod) – nestálá struktura – přidávání prvku ≈ přepočet půlku struktury – vhodné pouze pro statické množiny Albert (1,12) Bert (2,3) Chuck (4,11) Donna (5,6) Fred (9,10 ) Eddy (7,8)

42 Vnořené množiny - vylepšení ● původní pravidlo : – každý uzel (s pozicí [left, right]) má přesně (right - left - 1) / 2 potomků ● vylepšení od Joe Celko : – vypuštěním výše uvedeného pravidla nechat větší mezery mezi left a right pro přidávané potomky ● nepomůže, pokud left a right můžou být pouze celá čísla, protože za nějakou dobu se zaplní libovolně velká mezera

43 Vnořené intervaly - definice ● jde o zobecnění vnořených množin ● hranice intervalů již nemusí být celá čísla – potřebujeme hustší doménu – podle potřeby můžou být racionální nebo reálné čísla ● nadále platí : uzel p je předkem uzlu c právě když p.left <= c.left <= c.right <= p.right ● je několik způsobů jak umístit do struktury nový uzel

44 Vnořené intervaly - 1.způsob ● najdeme volný úsek uvnitř intervalu rodiče ● pak vkládaný uzel bude [(2*left1 + right1)/3, (left1 + 2*right1)/3] ● a pro další potomky toho rodiče ještě jsou k dispozici : a p.leftleft1 2*left1 + right1)/3(left1 + 2*right1)/3 right1p.right

45 Vnořené intervaly - 2.způsob ● 2-dimenzionální model : – osa x je right – osa y je left ● relace „býti podmnožinou“ je částečné uspořádání y x 1 1.1 1.2 1.3

46 Vnořené intervaly - mapování ● kořen zvolíme libovolně, např. [0,1] ● každý uzel pak reprezentuje jeden pravoúhlý trojúhelník pod diagonálou ● definujeme 2 důležité body: – bod konvergence do hloubky ● průsečík diagonály a vertikály protínající uzel – bod konvergence do šířky ● průsečík diagonály a horizontály protínající uzel y x 1 1. 1 b.k. do hloubky b.k. do šířky

47 Vnořené intervaly - mapování2 ● pro každý uzel pozice jeho : – prvního syna je v polovině úsečky mezi uzlem a b.k. do hloubky – dalších synů je v polovině úsečky mezi předchozím synem a b.k. do šířky ● např.: uzel 1.2 je [ ¼, ½ ]

48 Vnořené intervaly - symetrie ● naše hustá doména nebude doména reálných ani racionálních čísel, ale doména dvojic zlomků ● symetrie – každý podstrom má stejnou strukturu – syn je zmenšený rodič – obdoba fraktálů

49 Vnořené intervaly - normalizace ● kvůli zmíněné symetrie souřadnice uzlu nejsou na sobě nezávislé ● z jejich sumy lze vypočítat složky x a y ● namísto dvojic zlomků stačí pamatovat součet dvojic, tj. jeden zlomek, tj. 2 celá čísla ● tím jsme se dostali na úroveň vnořených množin v množství uchovávaných dat na jeden uzel

50 Vnořené intervaly - normalizace function x_numer( numer integer, denom integer ) RETURN integer IS ret_num integer; ret_den integer; BEGIN ret_num := numer+1; -- posun svisle nahoru na diagonálu ret_den := denom*2; -- souřadnice x je polovina podílu while floor(ret_num/2) = ret_num/2 loop -- redukce zlomku ret_num := ret_num/2; ret_den := ret_den/2; end loop; RETURN ret_num; -- pro čitatel -- RETURN ret_den; -- pro jmenovatel ve funkci x_denom() END;

51 Vnořené intervaly - normalizace function y_numer( numer integer, denom integer ) RETURN integer IS ret_num integer; ret_den integer; BEGIN ret_num := x_numer(numer, denom); -- získání čitatele x ret_den := x_denom(numer, denom); -- získání jmenovatele x while den < denom loop -- převést na společný jmenovatel ret_num := ret_num*2; ret_den := ret_den*2; end loop; ret_num := numer – ret_num; -- získat čitatel y while floor(ret_num/2) = ret_num/2 loop -- redukce zlomku ret_num := ret_num/2; ret_den := ret_den/2; end loop; RETURN ret_num;-- pro čitatel END; -- RETURN ret_den; -- pro jmenovatel ve funkci y_denom()

52 Vnořené intervaly - příklad1 SELECT x_numer(39,32) || '/' || x_denom(39,32), y_numer(39,32) || '/' || y_denom(39,32) FROM dual; 5/819/32 SELECT 5/8 + 19/32 FROM dual; 1.218751.21875 == 39/32

53 Funkce – pozice rodiče function parent_numer( numer integer, denom integer ) RETURN integer IS ret_num integer; ret_den integer; BEGIN if numer = 3 then -- uzel nejvyšší úrovně return NULL; end if; ret_num := (numer-1)/2; -- posun svisle dolů ret_den := denom/2; -- posun vodorovně doprava while floor((ret_num-1)/4) = (ret_num-1)/4 loop ret_num := (ret_num+1)/2; ret_den := ret_den/2; end loop; RETURN ret_num; -- pro čitatel END; -- RETURN ret_den; -- pro jmenovatel

54 Funkce – pořadí mezi sourozenci function sibling_number( numer integer, denom integer ) RETURN integer IS ret_num integer; ret_den integer; ret integer; BEGIN -- uzel nejvyšší úrovně + posun svisle dolů jako v předchozím ret := 1;-- inicializace pořadí na 1 while floor((ret_num-1)/4) = (ret_num-1)/4 loop -- posun doprava if ret_num=1 and ret_den=1 then return ret;-- zkoumaný uzel je první syn end if; ret_num := (ret_num+1)/2; ret_den := ret_den/2; ret := ret+1;-- každá iterace znamená posun o 1 sourozence end loop; RETURN ret; -- pořadí mezi sourozenci END;

55 Vnořené intervaly - příklad2 Uzel 2.1.2 má pozici 27/32 a uzel 2.1 (rodič předchozího) má 7/8 SELECT parent_numer(27,32) || '/' || parent_denom(27,32) FROM dual; 7/8 SELECT sibling_number(27,32) FROM dual; 2

56 Funkce – materializovaná cesta function path( numer integer, denom integer ) RETURN varchar2 IS BEGIN if numer is NULL then-- konec rekurze return ''; end if; RETURN --rekurzivně získá cestu k rodiči path( parent_numer(numer, denom), parent_denom(numer, denom) ) -- připojí pořadí aktualního uzlu mezi svými sourozenci || '.' || sibling_number(numer, denom); END; SELECT path(15,16) FROM dual;.2.1.1

57 Funkce – vzdálenost dvou uzlů function distance( num1 integer, den1 integer, num2 integer, den2 integer ) RETURN integer IS BEGIN if num1 is NULL then-- signalizuje, ze uzel num2/den2 není return -999999;-- předkem uzlu num1/den1 end if; if num1=num2 and den1=den2 then return 0;-- došli jsme do num2/den2 end if; RETURN1+distance(-- rekurze na rodiče + zvýšení délky cesty parent_numer(num1, den1), parent_denom(num1, den1), num2, den2 ); END; SELECT distance(27,32,3,4) FROM dual; 2

58 Funkce – čtení materializované cesty ● Funkce : function path_numer( path varchar2 ) RETURN integer function path_denom( path varchar2 ) RETURN integer parsují vstupní řetězec a na každé úrovni pomoci pozice rodiče a pořadí aktuálního uzlu mezi sourozenci vypočítávají pozici aktuálního uzlu SELECT path_numer('2.1.3') || '/' || path_denom('2.1.3') FROM dual; 51/64

59 Test struktury – definice schématu ● předpokládejme, že v tabulce emps máme uložené zaměstnance a jejich pozice získané z materializovaných cest v tabulce vpravo ● create table emps ( name varchar2(30), numer integer, denom integer ) ● tabulku naplníme sekvencí INSERTů tvaru : INSERT INTO emps VALUES ( 'FORD', path_numer('1.1.2'),path_denom('1.1.2') );

60 Test struktury – definice schématu ● z tabulky emps a ze zatím definovaných funkcí vytvoříme pohled, nad kterým se bude dobře dotazovat : CREATE OR REPLACE VIEW hierarchy AS SELECT name, numer, denom, y_numer(numer,denom) numer_left, y_denom(numer,denom) denom_left, x_numer(numer,denom) numer_right, x_denom(numer,denom) denom_right, path (numer,denom) path, distance(numer,denom,3,2) depth FROM emps;

61 Test struktury – procházka do hloubky Výsledek: LPAD('',3*DEPTH) || NAME --------------------------------------- KING CLARK MILLER BLAKE WARD ALLEN JONES FORD SMITH SCOTT ADAMS Dotaz : SELECT lpad(' ',3*depth)||name FROM hierarchy ORDER BY numer_left/ denom_left; Zdroj :

62 Test struktury – procházka do hloubky Výsledek: LPAD('',3*DEPTH) || NAME --------------------------------------- KING JONES SCOTT ADAMS FORD SMITH BLAKE ALLEN WARD CLARK MILLER Dotaz : SELECT lpad(' ',3*depth)||name FROM hierarchy ORDER BY numer_right / denom_right; Zdroj :

63 Test struktury – podřízené Výsledek: NAME ------------------------------ SCOTT ADAMS FORD SMITH Dotaz : SELECT h1.name FROM hierarchy h1, hierarchy h2 WHERE h2.name = 'JONES' AND distance( h1.numer, h1.denom, h2.numer, h2.denom) > 0 ; Zdroj :

64 Test struktury – nadřízené Výsledek: NAME ------------------------------ KING JONES Dotaz : SELECT h2.name FROM hierarchy h1, hierarchy h2 WHERE h1.name = 'FORD' AND distance( h1.numer, h1.denom, h2.numer, h2.denom) > 0 ; Zdroj :

65 Zdroje ● zdrojem pro referát sloužil článek od Vadim Tropashko : Trees in SQL: Nested Sets and Materialized Path http://www.dbazine.com/oracle/or-articles/tropashko4 http://www.dbazine.com/oracle/or-articles/tropashko4 ● navazující témata : Nested Intervals with Farey Fractions http://arxiv.org/html/cs.DB/0401014 http://arxiv.org/html/cs.DB/0401014 ● newsgroups : comp.database.theory comp.database.oracle


Stáhnout ppt "Stromy a hierarchické struktury v SQL 30.11.2005 Mária Szabó, Jirka Zouhar, Gergely Jakab."

Podobné prezentace


Reklamy Google