home *** CD-ROM | disk | FTP | other *** search
/ PC World 2005 May / PCWorld_2005-05_cd.bin / novinky / Interval / clanek04.htm < prev    next >
Encoding:
Extensible Markup Language  |  2005-04-02  |  25.9 KB  |  290 lines

  1. <?xml version='1.0' encoding='windows-1250'?>
  2. <!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Strict//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd'>
  3. <html xmlns='http://www.w3.org/1999/xhtml' xml:lang='cs' lang='cs'>
  4. <head>
  5. <meta http-equiv='Content-Type' content='text/html; charset=windows-1250' />
  6. <meta http-equiv='Content-language' content='cs' />
  7. <meta http-equiv='Cache-control' content='no-cache' />
  8. <meta http-equiv='Pragma' content='no-cache' />
  9. <meta http-equiv='Expires' content='-1' />
  10. <meta name='robots' content='index,follow' />
  11. <meta name='googlebot' content='index,follow,snippet,noarchive' />
  12. <meta name='description' content='Interval.cz - Internetov² magazφn o webdesignu, v²voji webov²ch aplikacφ a e-komerci. VÜe podstatnΘ o technologiφch XHTML, HTML, CSS, DHTML, JavaScript, XML, .NET, ASP, PHP, Java, J2ME, SQL, WAP...' />
  13. <meta name='keywords' content='Interval' />
  14. <meta name='ICBM' content='49.1915, 16.626' />
  15. <meta name='DC.Title' content='Interval.cz' />
  16. <meta name='DC.Identifier' content='http://interval.cz' />
  17. <meta name='DC.Language' content='cs' />
  18. <meta http-equiv='pics-label' content='(pics-1.1 "http://www.icra.org/ratingsv02.html" comment "ICRAonline EN v2.0" l gen true for "http://interval.cz" r (nz 1 vz 1 lz 1 oz 1 cz 1) "http://www.rsac.org/ratingsv01.html" l gen true for "http://interval.cz" r (n 0 s 0 v 0 l 0))' />
  19. <meta http-equiv='imagetoolbar' content='no' />
  20. <meta http-equiv='MSThemeCompatible' content='no' />
  21. <meta name='MSSmartTagsPreventParsing' content='true' />
  22. <link rel='shortcut icon' type='image/x-icon' href='favicon.ico' />
  23. <link rel='alternate' type='application/rss+xml' title='RSS Interval.cz' href='http://interval.cz/__rss/rss.asp' />
  24. <link rel='home' href='http://interval.cz' />
  25. <link rel='search' href='http://interval.cz/search_ex.asp' />
  26. <link rel='stylesheet' type='text/css' media='all' href='__services/styles/html4.css' />
  27. <link rel='stylesheet' type='text/css' media='all' href='__services/styles/interval-display.css' />
  28. <link rel='stylesheet' type='text/css' media='print' href='__services/styles/interval-print.css' />
  29. <title>Metody uklßdßnφ stromov²ch dat v relaΦnφch databßzφch -- Databßze -- V²voj aplikacφ -- Interval.cz</title>
  30. </head>
  31. <body class='interval interval-articles'>
  32. <div id='page-header'><div id='interval-logo'><h1 title='Interval.cz - denn∞ o tvorb∞ webu a e-komerci (logo & index link)'><a href='http://interval.cz/__redirect/redirect.asp?what=interval_offline&url=http://interval.cz'>Interval.cz<span></span></a></h1></div><div id='advertising-page-header'></div><div class='page-maker'> </div></div>
  33. <div id='page-topmenu'><h2 class='textversion'>Navigace</h2><div id='page-mainmenu'><h3 class='textversion'>Hlavnφ menu</h3><ul><li class='first selected'><a href='http://interval.cz/__redirect/redirect.asp?what=interval_offline&url=http://interval.cz'>Titulnφ strana</a></li><li><a href='http://interval.cz/__redirect/redirect.asp?what=interval_offline&url=http://interval.cz?idcategory=14'>Webdesign</a></li><li><a href='http://interval.cz/__redirect/redirect.asp?what=interval_offline&url=http://interval.cz?idcategory=15'>V²voj aplikacφ</a></li><li><a href='http://interval.cz/__redirect/redirect.asp?what=interval_offline&url=http://interval.cz?idcategory=18'>E-komerce</a></li><li><a href='http://interval.cz/__redirect/redirect.asp?what=interval_offline&url=http://interval.cz?idcategory=17'>Nßstroje</a></li><li><a href='http://interval.cz/__redirect/redirect.asp?what=interval_offline&url=http://interval.cz?idcategory=16'>Magazφn</a></li><li class='right selected'><a href='http://interval.cz/__redirect/redirect.asp?what=interval_offline&url=http://interval.inshop.cz'>Knihkupectvφ</a></li><li class='right'><a href='http://interval.cz/__redirect/redirect.asp?what=interval_offline&url=http://interforum.interval.cz'>Interforum</a></li></ul></div><div id='page-mainmenu-maker'> </div></div>
  34. <div id='page-body'><div id='page-left'><div id='article'>
  35.  
  36.  
  37. <h2>Metody uklßdßnφ stromov²ch dat v relaΦnφch databßzφch</h2>
  38. <p id='prepend'>StromovΘ datovΘ struktury p°edstavujφ pro relaΦnφ databßze pom∞rn∞ t∞₧ko stravitelnΘ sousto. ProblΘmy vypl²vajφ ze samotnΘ podstaty relaΦnφho databßzovΘho modelu, kter² nenφ pro uklßdßnφ tohoto typu dat p°φliÜ vhodn². Dosßhnout toho, aby byla prßce s t∞mito strukturami efektivnφ, p°edstavuje nelehk² ·kol. Tento Φlßnek se sna₧φ p°iblφ₧it n∞kolik p°φstup∙ k uklßdßnφ stromov²ch dat v relaΦnφ databßzi.</p>
  39.  
  40. <h3>┌skalφ relaΦnφch databßzφ</h3>
  41. <p>RelaΦnφ databßzovΘ systΘmy stßle z∙stßvajφ nejpou₧φvan∞jÜφm typem databßzov²ch systΘm∙, i kdy₧ mßme ji₧ n∞kolik let k dispozici v mnoha ohledech pokroΦilejÜφ objektovΘ databßze (nap°φklad <a href='http://www.gemstone.com'>gemstone</a>). Jedna z nejv∞tÜφch v²hod objektov²ch databßzφ je snadnß prßce se slo₧it∞ strukturovan²mi daty. Naopak relaΦnφ databßze vyu₧φvajφcφ k uklßdßnφ dat ploch²ch relaΦnφch tabulek majφ s t∞mito daty znaΦnΘ potφ₧e.</p>
  42. <p>KonkrΘtnφm p°φpadem obtφ₧n∞ zpracovateln²ch dat jsou data s hierarchickou, respektive stromovou strukturou. V objektovΘ databßzi mohou b²t stromovß data ulo₧ena p°φmo v takovΘ podob∞, jakou vyu₧φvß aplikace, kterß se k tΘto databßzi p°ipojuje. Naopak p°i pou₧itφ relaΦnφ databßze musφme data transformovat tak, abychom je mohli ulo₧it do plochΘ relaΦnφ tabulky, a p°i Φtenφ dat z databßze je musφme zp∞tn∞ transformovat do podoby stromu. Tento Φlßnek popisuje n∞kolik p°φstup∙, kterΘ se dajφ pou₧φt pro uklßdßnφ stromov²ch dat v relaΦnφ databßzi.</p>
  43.  
  44. <h3>┌vod do popisu metod</h3>
  45. <p>Hlavnφ pozornost jsem v∞noval datovΘ struktu°e a algoritm∙m, kter²mi se mohou stromovß data zpracovßvat (zφskßvat a editovat). P°φklady jsem realizoval v jazyce PHP pro jeho jednoduchost, ·spornost a rozÜφ°enost. UvedenΘ p°φklady ale nenφ problΘm realizovat v jakΘmkoli jinΘm procedurßlnφm jazyce. Rßd bych zd∙raznil, ₧e veÜker² programov² k≤d v Φlßnku je zam∞°en p°edevÜφm na algoritmy, proto berte s nadhledem nap°φklad zp∙sob formßtovßnφ v²pisu stromu pomocφ tvrd²ch mezer a <code><br /></code>. Ka₧d² si samoz°ejm∞ tuto Φßst m∙₧e napsat dle sv²ch pot°eb. Jako ukßzkov² p°φklad stromovΘ struktury jsem vybral strom kategoriφ zbo₧φ, se kter²m se m∙₧eme setkat v libovolnΘm eShopu. Takov² strom m∙₧e vypadat nap°φklad takto:</p>
  46.  
  47. <div class='image'>
  48. <img src='podklady/zelenka/1120/strom.png' alt='Stromovß struktura' title='Stromovß struktura' />
  49. <br /><span class='comment'>Obrßzek Φ. 1: P°φklad stromovΘ struktury</span>
  50. </div>
  51.  
  52. <h3>Klasick² p°φstup</h3>
  53. <p>Nejznßm∞jÜφm a takΘ nejΦast∞ji vyu₧φvan²m zp∙sobem, kter² lze p°i uklßdßnφ stromov²ch struktur do relaΦnφ databßze pou₧φt, je model, kdy je souΦßstφ ka₧dΘho prvku stromu takΘ reference na prvek rodiΦovsk². Nejv²Üe postaven² prvek stromu, zvan² ko°en, mß referenci nastavenou na 0 nebo NULL.</p>
  54.  
  55. <div class='table'>
  56. <table cellspacing='0'>
  57. <tr><th>ID</th><th>NAME</th><th>PARENT_ID</th></tr>
  58. <tr><td>1</td><td>Kategorie zbo₧φ</td><td>0</td></tr>
  59. <tr><td>2</td><td>Procesory</td><td>1</td></tr>
  60. <tr><td>3</td><td>Intel</td><td>2</td></tr>
  61. <tr><td>4</td><td>Pentium IV</td><td>3</td></tr>
  62. <tr><td>5</td><td>Celeron</td><td>3</td></tr>
  63. <tr><td>6</td><td>AMD</td><td>2</td></tr>
  64. </table>
  65. <span class='comment'>Tabulka Φ. 1: Klasickß datovß struktura pro ulo₧enφ stromu v relaΦnφ tabulce</span>
  66. </div>
  67.  
  68. <h4>Zφskßvßnφ dat rekurzφ</h4>
  69. <p>Pro zφskßvßnφ dat z takovΘto tabulky se dß s ·sp∞chem vyu₧φt rekurzivnφ funkce, viz ukßzka Φ. 1. Tato funkce se m∙₧e volat z jakΘhokoli uzlu stromu. VypφÜe potomky p°φsluÜnΘho uzlu s <samp>ID</samp> rovn²m argumentu <samp>$parent</samp> a pro vÜechny potomky je poslΘze volanß rekurzivn∞. Argument <samp>$level</samp> udßvß zano°enφ p°φsluÜnΘho uzlu, kter² slou₧φ pro rozliÜenφ uzlu p°i v²pisu stromu. Pro zobrazenφ celΘho stromu by se funkce volala s ob∞ma argumenty nastaven²mi na nulu.</p>
  70. <p>Ukßzka Φ. 1: <em>Rekurzivnφ funkce pro zφskßnφ stromu z DB</em></p>
  71.  
  72. <div class='sample'>
  73. function getTree($parent, $level) {
  74. <br />  $result = mysql_query('SELECT * FROM TREE WHERE PARENT_ID='.$parent);
  75. <br />  while ($row = mysql_fetch_assoc($result)) {
  76. <br />    echo str_repeat("&nbsp;",$level).$row['NAME']."<br />";
  77. <br />    getTree($row['ID'], $level++);
  78. <br />  }
  79. <br />}
  80. </div>
  81.  
  82. <p>Je z°ejmΘ, ₧e v dob∞ objektovΘho programovßnφ bychom se s uveden²m p°φkladem asi nespokojili. Pravd∞podobn∞ bychom pro reprezentaci uvedenΘho stromu vytvo°ili t°φdu. JednotlivΘ uzly stromu by vznikaly jako instance tΘto t°φdy a ka₧d² uzel by souΦasn∞ sklßdal svΘ pod°φzenΘ uzly. V²sledkem by tedy byl rekurzivnφ objekt p°edstavujφcφ cel² strom nebo jeho libovolnou Φßst. Principy zφskßnφ dat pot°ebn²ch pro napln∞nφ tohoto objektu by ovÜem z∙staly zcela stejnΘ. Uveden² algoritmus by se ale pou₧il v rekurzivnφm konstruktoru tΘto t°φdy. Nßsleduje p°φklad t°φdy implementovanΘ v jazyce PHP.</p>
  83. <p>Ukßzka Φ. 2: <em>T°φda pro vytvo°enφ rekurzivnφch objekt∙</em></p>
  84.  
  85. <div class='sample'>
  86. Class CTreeNode
  87. <br />{
  88. <br />  var $id = 0;
  89. <br />  var $name ='';
  90. <br />  var $level = 0;
  91. <br />  var $childNodes = array();
  92. <br />  function CTreeNode($id,$name,$level)
  93. <br />  {
  94. <br />    $this->id=$id;
  95. <br />    $this->name=$name;
  96. <br />    $this->level=$level;
  97. <br />    $result = mysql_query("SELECT * FROM TREE WHERE PARENT_ID=$id");
  98. <br />     while ($r = mysql_fetch_assoc($result)) {
  99. <br />      $this->childNodes[] = new CtreeNode($r['ID'], $r['NAME'], $level++);
  100. <br />    }
  101. <br />  }
  102. <br />}
  103. </div>
  104.  
  105. <p>T°φdu bychom samoz°ejm∞ museli doplnit o metody pro prezentaci dat, kterΘ by op∞t musely b²t rekurzivnφ a fungovaly by na obdobnΘm principu. (Eventueln∞ by mohly vyu₧φvat XSLT, pak by byl problΘm p°enesen na transformaΦnφ procesor.)</p>
  106.  
  107. <h4>Zφskßvßnφ dat s vyu₧itφm zßsobnφku</h4>
  108. <p>Druhou alternativou, kterou m∙₧eme s ·sp∞chem pou₧φt pro zφskßnφ dat z databßze, je pou₧itφ zßsobnφku. Vyu₧itφ zßsobnφku nßm nep°inßÜφ ₧ßdnou ·sporu SQL dotaz∙, ale p°inßÜφ zv²Üenφ efektivity aplikaΦnφho k≤du. Mφsto rekurzivnφho volßnφ funkce Φi metody se pou₧ije pouze obyΦejn² "while" cyklus. Je z°ejmΘ, ₧e pro v∞tÜφ objem dat bude metoda s vyu₧itφm zßsobnφku efektivn∞jÜφ. Nßsleduje funkce implementovanß v jazyce PHP. Pro zßsobnφk bylo vyu₧ito pole, pro kterΘ jsou definovßny funkce pot°ebnΘ k prßci se zßsobnφkem (<code>push</code> a <code>pop</code>).</p>
  109. <p>Ukßzka Φ. 3: <em>Vyu₧itφ zßsobnφku pro zφskßnφ stromu z DB</em></p>
  110.  
  111. <div class='sample'>
  112. function getTree($nodeId)
  113. <br />{
  114. <br />  $stack = array();
  115. <br />  $level = 0;
  116. <br />  $res = mysql_query('SELECT ID, NAME FROM TREE WHERE ID='.$nodeId);
  117. <br />  $row = mysql_fetch_assoc($result);
  118. <br />  $row['LEVEL'] = 0;
  119. <br />  array_push($stack, $row);
  120. <br />  while(count($stack)>0)
  121. <br />  {
  122. <br />    $r = array_pop($stack);
  123. <br />    echo str_repeat("&nbsp;",$r['LEVEL']).$r['NAME']."<br />";
  124. <br />    $res = mysql_query('SELECT ID, NAME FROM TREE WHERE PARENT_ID='.$r['ID']);
  125. <br />    if(mysql_num_rows($res)>0) {
  126. <br />      $level = $r['LEVEL']+1;
  127. <br />    }
  128. <br />    while($row = mysql_fetch_assoc($result)) {
  129. <br />      $row['LEVEL'] = $level;
  130. <br />      array_push($stack, $row);
  131. <br />    }
  132. <br />  }
  133. <br />}
  134. </div>
  135.  
  136. <h4>Editace dat</h4>
  137. <p>Editace dat je v tomto p°φpad∞ naprosto trivißlnφ. P°i uklßdßnφ novΘho uzlu staΦφ znßt <samp>ID</samp> nad°azenΘ kategorie. P°esun v∞tve do jinΘ Φßsti stromu je takΘ velice jednoduch², staΦφ pouze zm∞nit <samp>PARENT_ID</samp> danΘho uzlu.</p>
  138.  
  139. <h4>Zhodnocenφ metody</h4>
  140. <p>Tato metoda je velice jednoduchß, snadno pochopitelnß i realizovatelnß. Editace dat je nenßroΦnß a rychlß. Jedin²m problΘmem je zφskßvßnφ dat. V uvedenΘm p°φkladu by pou₧itφ rekurzivnφ funkce na zφskßnφ dat znamenalo provΘst pro n uzl∙ takΘ n dotaz∙ do databßze. Vyu₧itφ rekurzivnφ funkce je sice elegantnφ, ale nenφ p°φliÜ efektivnφ. UrΦitΘ zlepÜenφ by mohlo p°inΘst pou₧itφ zßsobnφku. PoΦet dotaz∙ do databßze ovÜem z∙stßvß stejn².</p>
  141.  
  142. <h4>Mo₧nΘ modifikace metody</h4>
  143. <p>Pro zmenÜenφ poΦtu dotaz∙ bychom mohli vyu₧φt zp∙sob, kdy cel² strom zφskßme jednφm dotazem do pole polφ a funkce, respektive konstruktor, by vyu₧ily toto pole pro napln∞nφ rekurzivnφho objektu. Zatφ₧enφ databßze by se snφ₧ilo, ale zase bychom radikßln∞ zv²Üili pam∞¥ovou nßroΦnost aplikace, kterß by takto data musela zpracovßvat.</p>
  144. <p>DalÜφ zp∙sob, kter² bychom mohli pou₧φt ke snφ₧enφ zßt∞₧e databßze, je v podstat∞ univerzßlnφ pro veÜkerΘ p°φstupy uvedenΘ v tomto Φlßnku. Zφskan² strom bychom mohli v serializovanΘ podob∞ dr₧et v databßzi a naÜe aplikace by si ho naΦφtala jako BLOB polo₧ku, na kterou by nßsledn∞ musela provΘst deserializaci. P°i jakΘkoli zm∞n∞ stromu by se do databßze musela uklßdat jeho aktußlnφ podoba. Takto ale m∙₧eme pracovat pouze se stromem jako celkem, co₧ m∙₧e b²t n∞kdy nedostaΦujφcφ. DalÜφmu mo₧nΘmu rozÜφ°enφ se v∞nuje nßsledujφcφ metoda.</p>
  145.  
  146. <h3>RozÜφ°enφ plochΘ tabulky</h3>
  147. <p>Pro zv²Üenφ efektivity modelu z p°edchozφ Φßsti, m∙₧eme datovou strukturu rozÜφ°it o dalÜφ atributy, kterΘ nßm umo₧nφ rychlejÜφ p°φstup k dat∙m. Bude to atribut <samp>ORD</samp>, kter² p°edstavuje po°adφ uzlu v danΘm stromu, a atribut <samp>LEVEL</samp>, kter² p°edstavuje zano°enφ, respektive ·rove≥ uzlu.</p>
  148.  
  149. <div class='table'>
  150. <table cellspacing='0'>
  151. <tr><th>ID</th><th>NAME</th><th>PARENT_ID</th><th>ORD</th><th>LEVEL</th></tr>
  152. <tr><td>1</td><td>Kategorie zbo₧φ</td><td>0</td><td>1</td><td>0</td></tr>
  153. <tr><td>2</td><td>Procesory</td><td>1</td><td>2</td><td>1</td></tr>
  154. <tr><td>3</td><td>Intel</td><td>2</td><td>3</td><td>2</td></tr>
  155. <tr><td>4</td><td>Pentium IV</td><td>3</td><td>4</td><td>3</td></tr>
  156. <tr><td>5</td><td>Celeron</td><td>3</td><td>5</td><td>3</td></tr>
  157. <tr><td>6</td><td>AMD</td><td>2</td><td>6</td><td>2</td></tr>
  158. </table>
  159. <span class='comment'>Tabulka Φ. 2: RozÜφ°enφ klasickΘho p°φstupu o po°adφ a hloubu zano°enφ</span>
  160. </div>
  161.  
  162. <h4>Zφskßvßnφ dat</h4>
  163. <p>Takto ulo₧enß data m∙₧eme samoz°ejm∞ vypisovat stejn²m zp∙sobem jako v prvnφm p°φpad∞, ale m∙₧eme takΘ pou₧φt velice jednoduch² zp∙sob v²pisu, p°i kterΘm vyu₧ijeme p°idanΘ atributy.</p>
  164. <p>Ukßzka Φ. 4: <em>P°φm² v²pis stromu z databßze</em></p>
  165.  
  166. <div class='sample'>
  167. function getTree() {
  168. <br />  $result = mysql_query('SELECT * FROM TREE ORDER BY ORD ASC');
  169. <br />  while ($row = mysql_fetch_array($result)) {
  170. <br />    echo str_repeat("&nbsp;",$row['LEVEL']).$row['NAME']."<br />";
  171. <br />  }
  172. <br />}
  173. </div>
  174.  
  175. <p>Jak je vid∞t z p°φkladu, v²pis je velice jednoduch² a rychl². Na databßzi staΦφ poslat pouze jeden dotaz.</p>
  176.  
  177. <h4>Editace dat</h4>
  178. <p>Jednoduchost, kterou jsme dosßhli p°i zφskßvßnφ dat, byla vykoupena nßroΦnostφ vklßdßnφ nov²ch dat, a to p°edevÜφm kv∙li nutnosti dopoΦφtat ·daje o hloubce a hlavn∞ po°adφ. ZjiÜt∞nφ hloubky p°edstavuje trivißlnφ p°iΦtenφ Φφsla <samp>1</samp> k hloubce nad°azenΘho uzlu. P°i vlo₧enφ ale musφme takΘ zadat po°adφ. Pokud se zßznamy °adφ podle Φasu, p°idßme jednoduÜe zßznam na prvnφ nebo poslednφ mφsto mezi d∞tmi v p°φsluÜnΘ ·rovni. Jedinou podmφnkou je nßsledn² <samp>UPDATE</samp> vÜech zßznam∙ s v∞tÜφm a stejn²m po°adφm, ne₧ je po°adφ vklßdanΘho zßznamu. P°i vklßdßnφ zßznam∙ °azen²ch dle abecedy je situace trochu slo₧it∞jÜφ, musφme toti₧ nejprve set°φdit d∞ti danΘho uzlu a zjistit, na jakΘ mφsto p°ijde nßÜ nov² zßznam.</p>
  179.  
  180. <h4>Zhodnocenφ metody</h4>
  181. <p>Popsanß metoda umo₧≥uje jednoznaΦn∞ nejrychlejÜφ zp∙sob v²pisu dat. Rychlost v²pisu je ale vykoupena slo₧itostφ vklßdßnφ. Jeliko₧ ve v∞tÜin∞ p°φpad∙ preferujeme rychlost v²pisu p°ed rychlostφ editace, nep°edstavuje toto omezenφ p°φliÜ velk² problΘm.</p>
  182.  
  183. <h3>Traverzovßnφ kolem stromu</h3>
  184. <p>Traverzovßnφ kolem stromu, respektive <strong>Modified Preorder Tree Traversal Algoritmus</strong>, je dalÜφm ze zp∙sob∙, kter²m m∙₧eme rozÜφ°it datovou strukturu pro ulo₧enφ stromovΘ struktury do relaΦnφ databßze. Princip spoΦφvß v ohodnocenφ uzl∙ stromu dv∞ma hodnotami tφm zp∙sobem, ₧e od ko°enu obchßzφme vÜechny v∞tve stromu a postupn∞ dopl≥ujeme pravou a levou hodnotu uzlu, dokud se nevrßtφme zp∞t ke ko°enu. Ko°en mß tφm pßdem nejmenÜφ levou a nejv∞tÜφ pravou hodnotu ze vÜech uzl∙ stromu. NßÜ zkuÜebnφ p°φklad bychom mohli ohodnotit zp∙sobem, kter² ukazuje obrßzek Φ. 1.</p>
  185.  
  186. <div class='image'>
  187. <img src='podklady/zelenka/1120/strom-traverz.png' alt='Ohodnocenφ uzl∙ stromu' title='Ohodnocenφ uzl∙ stromu' />
  188. <br /><span class='comment'>Obrßzek Φ. 2: Zp∙sob ohodnocenφ uzl∙ traverzovßnφm kolem stromu</span>
  189. </div>
  190.  
  191. <div class='table'>
  192. <table cellspacing='0'>
  193. <tr><th>ID</th><th>NAME</th><th>PARENT_ID</th><th>LFT</th><th>RGT</th></tr>
  194. <tr><td>1</td><td>Kategorie zbo₧φ</td><td>0</td><td>1</td><td>22</td></tr>
  195. <tr><td>2</td><td>Procesory</td><td>1</td><td>2</td><td>15</td></tr>
  196. <tr><td>3</td><td>Intel</td><td>2</td><td>3</td><td>8</td></tr>
  197. <tr><td>4</td><td>Pentium IV</td><td>3</td><td>4</td><td>5</td></tr>
  198. <tr><td>5</td><td>Celeron</td><td>3</td><td>6</td><td>7</td></tr>
  199. <tr><td>6</td><td>AMD</td><td>2</td><td>9</td><td>14</td></tr>
  200. </table>
  201. <span class='comment'>Tabulka Φ. 3: Datovß struktura a hodnoty zφskanΘ traverzovßnφm kolem stromu</span>
  202. </div>
  203.  
  204. <h4>Zφskßvßnφ dat</h4>
  205. <p>Z obrßzku Φ. 1 m∙₧eme vyΦφst, ₧e pod°φzenΘ uzly majφ pravou a levou hodnotu v₧dy v intervalu nad°φzenΘho uzlu. VÜechny uzly nachßzejφcφ se pod dan²m uzlem se dajφ zφskat dotazem na vÜechny uzly s levou hodnotou v intervalu pravΘ a levΘ hodnoty danΘho uzlu.</p>
  206. <p>Nßsledujφcφ p°φklad p°edstavuje algoritmus, kter²m zφskßme libovolnou Φßst stromu z databßze pouze dv∞ma dotazy. Jeliko₧ v tabulce neuklßdßme ·rove≥ zano°enφ, musφme pou₧φt zßsobnφk prav²ch hodnot k zφskßnφ ·rovn∞ danΘho uzlu.</p>
  207. <p>Ukßzka Φ. 5: <em>V²pis stromu z databßze (tree traversal)</em></p>
  208.  
  209. <div class='sample'>
  210. function getTree($nodeId) {
  211. <br />  $result = mysql_query('SELECT LFT, RGT FROM TREE WHERE ID='.$nodeId);
  212. <br />  $row = mysql_fetch_array($result);
  213. <br />  $rightStack = array();
  214. <br />  $result = mysql_query('SELECT NAME, LFT, RGT FROM TREE WHERE LFT BETWEEN '.$row['LFT'].' AND '.$row['RGT'].' ORDER BY lft ASC');
  215. <br />  while ($row = mysql_fetch_array($result)) {
  216. <br />    if (count($rightStack)>0) {
  217. <br />      while ($rightStack[count($rightStack)-1]<$row['RGT']) {
  218. <br />        array_pop($rightStack);
  219. <br />      }
  220. <br />    }
  221. <br />    echo str_repeat("&nbsp;",count($rightStack)).$row['NAME']."<br >";
  222. <br />    $rightStack[] = $row['RGT'];
  223. <br />  }
  224. <br />}
  225. </div>
  226.  
  227. <p>Uveden² zp∙sob nemß pouze v²hodu rychlΘho zφskßnφ stromu z databßze, ale m∙₧eme pom∞rn∞ efektivn∞ zφskßvat dalÜφ informace. Nap°φklad pokud chceme v∞d∞t, kolik uzl∙ je pod°φzen²ch p°φsluÜnΘmu uzlu, a znßme p°itom jeho pravou a levou hodnotu, zjistφme tuto hodnotu jednoduch²m v²poΦtem <samp>(RGT-LFT-1)/2</samp>. Pokud chceme zjistit cestu od danΘho uzlu ke ko°enu, staΦφ abychom se dotßzali na vÜechny uzly s <samp>LFT</samp> menÜφ ne₧ <samp>LFT</samp> danΘho uzlu a <samp>RGT</samp> v∞tÜφ ne₧ <samp>RGT</samp> tohoto uzlu. Takto zφskßme cestu pomocφ jednoho dotazu. Nap°φklad pro Duron bychom cestu ke ko°enu zφskali dotazem <samp>SELECT * FROM TREE WHERE LFT<10 AND RGT>11</samp>.</p>
  228.  
  229. <h4>Editace dat</h4>
  230. <p>Rychlost zφskßvßnφ dat je op∞t vykoupena slo₧itostφ modifikace struktury stromu. Nelze jednoduÜe vklßdat novΘ zßznamy. Po ka₧dΘm vlo₧enφ je nutnΘ p°eΦφslovat levΘ a pravΘ hodnoty.</p>
  231. <p>Ukßzka Φ. 6: <em>Aktualizace zßznam∙ v databßzi (tree traversal)</em></p>
  232.  
  233. <div class='sample'>
  234. function rebuildTree($parent, $left) {
  235. <br />  $right = $left+1;
  236. <br />  $result = mysql_query('SELECT ID, NAME FROM TREE WHERE PARENT_ID='.$parent);
  237. <br />  while ($row = mysql_fetch_array($result)) {
  238. <br />    $right = rebuild_tree($row['ID'], $right);
  239. <br />  }
  240. <br />  mysql_query('UPDATE TREE SET LFT='.$left.', RGT='.$right.' WHERE ID='.$parent);
  241. <br />  return $right+1;
  242. <br />}
  243. </div>
  244.  
  245. <h4>Zhodnocenφ metody</h4>
  246. <p>Tato metoda je pravd∞podobn∞ nejkomplexn∞jÜφ ze vÜech uveden²ch metod a p°inßÜφ nejvφce mo₧nostφ pro jednoduchΘ zφskßvßnφ dat z databßze. Tyto v²hody jsou op∞t vykoupeny slo₧it∞jÜφm uklßdßnφm a zm∞nou struktury stromu.</p>
  247.  
  248. <h3>Zhodnocenφ probranΘ metodiky</h3>
  249. <p>UvedenΘ metody nejsou zcela urΦit∞ ·pln²m v²Φtem vÜech mo₧n²ch p°φstup∙, ale pat°φ k t∞m nejΦast∞ji pou₧φvan²m. Je z°ejmΘ, ₧e nasazenφ objektovΘ databßze na tento typ dat by p°ineslo razantnφ zjednoduÜenφ prßce a pravd∞podobn∞ takΘ zrychlenφ aplikace.</p>
  250. <p>Bohu₧el v∞tÜφmu nasazenφ objektov²ch databßzφ brßnφ p°edevÜφm d∙vody historickΘ (valnß v∞tÜina starÜφch systΘm∙ vyu₧φvß relaΦnφ databßze) a ekonomickΘ. Vyu₧itφ objektov²ch databßzφ rovn∞₧ ubli₧uje obecnß p°edstava, ₧e co je objektovΘ, to je pomalΘ.</p>
  251.  
  252. <div id='article-author'>
  253. <a href='http://interval.cz/__redirect/redirect.asp?what=interval_offline&url=http://interval.cz/autor.asp?author=216'>Zelenka, Petr</a> (2. 3. 2005)
  254.  
  255. </div>
  256.  
  257.  
  258.  
  259.  
  260. </div></div>
  261. <div id='page-right'><h2 class='textversion'>Prav² sloupek</h2>
  262. <div id='search'><h3 class='textversion'>Vyhledßvßnφ</h3><form method='get' action='http://interval.cz/search.asp'><div><input type='text' name='hledej' class='text' /><input type='submit' class='submit' value='Najdi!' /></div></form><div><a href='http://interval.cz/search_ex.asp'>RozÜφ°enΘ vyhledßvßnφ</a></div></div>
  263.  
  264.  
  265.  
  266. <div class='page-right-box book'>
  267.     <h3>Kni₧nφ novinka</h3>
  268.     <div class='page-right-box-in'>
  269.         <div class='book-top'>
  270.             <h4><a href='http://interval.cz/__redirect/redirect.asp?what=interval_booknews&url=http://interval.inshop.cz/inshop/scripts/detail.asp?ItemID=290'>PHP - moduly, rozÜφ°enφ a akcelerßtory</a></h4>
  271.         </div>
  272.         <div class='image'>
  273.             <img src='podklady/knihy/image.jpg' alt='obßlka' title='obßlka' /></a>
  274.         </div>
  275.         <div class='book-bottom'>Cena: <span class='book-price-old'>299 KΦ</span> <span class='book-price-new'>269 KΦ</span></div>
  276.     </div>
  277. </div>
  278.  
  279.  
  280.  
  281. <div class='page-right-box reading'><h3 title='NejΦten∞jÜφ Φlßnky za poslednφch 14 dn∙'>NejΦten∞jÜφ</h3><div class='page-right-box-in'><ul><li><a href='http://interval.cz/__redirect/redirect.asp?what=interval_offline&url=http://interval.cz/clanek.asp?article=3829'>Interval.cz a jeho Φtenß°i v roce 2005</a></li><li><a href='http://interval.cz/__redirect/redirect.asp?what=interval_offline&url=http://interval.cz/clanek.asp?article=3830'>Pou₧φvßme nßvrhovΘ vzory v .NET - Singleton</a></li><li><a href='http://interval.cz/__redirect/redirect.asp?what=interval_offline&url=http://interval.cz/clanek.asp?article=3827'>SUN Java Studio Creator</a></li><li><a href='http://interval.cz/__redirect/redirect.asp?what=interval_offline&url=http://interval.cz/clanek.asp?article=3824'>Perl-compatible regulßrnφ v²razy v PHP - modifikßtory a lφnΘ kvantifikßtory</a></li><li><a href='http://interval.cz/__redirect/redirect.asp?what=interval_offline&url=http://interval.cz/clanek.asp?article=3831'>GNU Gettext - sprßva p°eklad∙</a></li></ul></div></div><div class='page-right-box cauldron'><h3 title='Nejdiskutovan∞jÜφ Φlßnky za poslednφch 21 dn∙'>Diskuznφ kotel</h3><div class='page-right-box-in'><ul><li><a href='http://interval.cz/__redirect/redirect.asp?what=interval_offline&url=http://interval.cz/clanek.asp?article=3818' title='(36 komentß°∙)'>PHP a MS SQL - vklßdßnφ a naΦφtßnφ soubor∙</a></li><li><a href='http://interval.cz/__redirect/redirect.asp?what=interval_offline&url=http://interval.cz/clanek.asp?article=3811' title='(26 komentß°∙)'>GNU Gettext - prvnφ kroky</a></li><li><a href='http://interval.cz/__redirect/redirect.asp?what=interval_offline&url=http://interval.cz/clanek.asp?article=3829' title='(20 komentß°∙)'>Interval.cz a jeho Φtenß°i v roce 2005</a></li><li><a href='http://interval.cz/__redirect/redirect.asp?what=interval_offline&url=http://interval.cz/clanek.asp?article=3815' title='(11 komentß°∙)'>H°φchy pro ÜφlenΘho korektora - jak se vyhnout zbyteΦn²m chybßm</a></li><li><a href='http://interval.cz/__redirect/redirect.asp?what=interval_offline&url=http://interval.cz/clanek.asp?article=3825' title='(11 komentß°∙)'>Ovlßdacφ prvok CAPTCHA v ASP.NET</a></li></ul></div></div>
  282.  
  283.  
  284.  
  285. <div class='page-right-box emailserv'><h3>Email servis</h3><div class='page-right-box-in'><form action='prihlaseni.asp' method='post'><div class='shell'><input class='text' type='text' name='adresa' /></div><div class='shell'><input class='radio' type='radio' value='1' name='co' checked='checked' />T²dennφ p°ehled Φlßnk∙</div><div class='shell'><input class='radio' type='radio' value='2' name='co' />HELP konference</div><div class='shell'><input class='submit' type='submit' value='P°ihlßsit' /></div></form></div></div>
  286. </div>
  287. <div class='page-maker'> </div><div class='page-maker-white'> </div></div>
  288. <div id='page-foot'><div id='page-foot-menu'><a href='http://interval.cz/reklama.asp'>Inzerce na Interval.cz</a> | <a href='http://interval.cz/redakce.asp'>Redakce Interval.cz</a> | <a href='http://interval.cz/autori.asp'>Hledßme novΘ autory</a></div><div id='issn'>ISSN 1212-8651</div><div id='page-foot-zoner'>© Zoner software, s.r.o., vÜechna prßva vyhrazena, tento server dodr₧uje <a href='http://interval.cz/privacy.asp'>prßvnφ p°edpisy</a>o ochran∞ osobnφch ·daj∙.</div></div>
  289. </body>
  290. </html>