Autor | Zpráva | ||
---|---|---|---|
maarlin Profil |
#1 · Zasláno: 29. 3. 2010, 14:30:42 · Upravil/a: maarlin
Mám běžnou strukturu kategorií, která se celá dá získat rekurzí.
id | name | parent_id -------------------------- 1 | Notebooky | 0 -------------------------- 2 | 15.4 | 1 a na to navázanou tabulku zboží, která je logicky navázaná na sloupec id. Když chci vypsat zboží z nějaké z kořenových kategorií (tj. kategorie, která má id=0), musím se doptat pokaždé na příslušné vnořené kategorie (děti té kořenové kategorie). <?php function findAllChildrenIds($categoryId, $data=array()) { $data[] = $categoryId; $category = $this->connection->select('*')->from($table) ->where('parent_id=%i', $categoryId)->fetchAll(); if (count ($category) > 0) { foreach ($category as $cat) { $this->findAllChildrenIds($cat->id, &$data); } } return $data; } ?> a pak je dosadit do dotazu, který mi vybere to patřičné zboží (samozřejmě tam je ještě implode): SELECT * FROM products WHERE category_id IN ($childrenIds) Postup sice relativně funguje, ale generuje nesnesitelné množství dotazů a tomu úměrný potřebný čas na zpracování (>4s), což se mi moc nelíbí. Nevíte prosím někdo, jak by se dal tento dotaz přepsat do jednoho, popř. dvou (třeba nějak za použití SQL proměnných)? |
||
Kajman_ Profil * |
#2 · Zasláno: 29. 3. 2010, 14:41:24
Mrkněte na využití pomocných předpočítaných sloupců, které takové dotazy urychlí.
http://dev.mysql.com/tech-resources/articles/hierarchical-data.html http://interval.cz/clanky/metody-ukladani-stromovych-dat-v-relacnich-databazich/ http://php.vrana.cz/traverzovani-kolem-stromu-prakticky.php |
||
maarlin Profil |
#3 · Zasláno: 29. 3. 2010, 14:51:58
Kajman:
> Mrkněte na využití pomocných předpočítaných sloupců, které takové dotazy urychlí. > > ht>tp://dev.mysql.com/tech-resources/articles/hierarchical-data.html > ht>tp://interval.cz/clanky/metody-ukladani-stromovych-dat-v-relacnich-databazich/ > ht>tp://php.vrana.cz/traverzovani-kolem-stromu-prakticky.php Díky, už jsem četl, jen jsem to zapomněl zmínit. Důvod, proč tam ponechávám "rekurzivní" strukturu je ten, že se mnoho kategorií často aktualizuje, resp. synchronizuje a ta synchronizace by v případě využití "traverzování" byla neskutečnou zátěží... představte si třeba 100 nových kategorií připravených k přidání a starých 1500... to máme 1500*100 přepočítání (=dotazů) celé tabulky... V takovém případě bych už snad i oželel ty 4sec při čtení z tabulky. |
||
Kajman_ Profil * |
#4 · Zasláno: 29. 3. 2010, 15:14:37
představte si třeba 100 nových kategorií připravených k přidání a starých 1500
Když vím, že budu dávat tolik nových, tak je přidám a teprve po všech přepočítám podle parent_id nové lft a rgt, tak to máte 1600 updatů jednoho řádku a selectů max 1600 (když bude 1600 úrovní). Jinak k původnímu dotazu, pokud traverzování není vhodné, tak pro 1600 kategoríí bych si asi udělal pole všech kategorí v php a v něm rekurzivně našel všechny id potomků a ty použil v dotaze. |
||
ninja Profil |
#5 · Zasláno: 29. 3. 2010, 15:25:43
SELECT * FROM products JOIN kategorie k1 ON category_id=k1.id LEFT JOIN kategorie k2 ON k1.parent_id=k2.id ... WHERE $categoryId_id IN (k1.id, k2.id, ...); Nevýhoda tohoto řešení je zřejmá, ale pokud jste schopen limitovat počet zanoření na nějakou rozumnou úroveň, je to použitelné. |
||
TomášK Profil |
#6 · Zasláno: 29. 3. 2010, 17:36:48 · Upravil/a: TomášK
Některé databáze podporují rekurzivní dotazy, od loňska i PostgreSQL. Jste-li vázán na MySQL, pak nezbývá než použít jiné řešení.
|
||
Časová prodleva: 14 let
|
0