FLWOR MySQLben
Halihó!
Ugyebár a relációs adatbázisok eredmánytáblát adnak vissza. Nem úgy, mint a FLWOR, az SQL képtelen hierarchiát (pontosabban az ehhez szükséges különböző egyedeket) egy eredménytáblában visszaadni. Érdekelne ki hogyan valósítja meg a hierarchikus logikát a lekérdezésekben. Itt van egykét megoldás amire gondolok, de mindegyiknek van valami kisebbnagyobb hibája.
A két tábla legyen "cikk" és "rovat". A "$where" pedig tételezzük fel, hogy valami közepesen bonyolult szűrő.
Egyesített query
Előny: egyetlen SQL lekérdezést kell csak értelmezni, végrehajtani, a MySQLnek.
Hátrány: nagy adatforgalom az adatbázis és a php között. Ha külön szerveren van az adatbázis, akkor még problémásabb.Párhuzamos queryk
Előny: nincs fölösleges adatforgalom, minden csak egyszer szerepel az eredményben.
Hátrány: Gyakorlatilag ugyanaz a query fut le kétszer. Nem tudom a MySQL mennyire tudja optimalizálni őket, kihasználja-e, hogy a WHERE igazsághalmaza ugyanaz a két lekérdezésben.Beágyazott SQL
Biztos lehet így is, de én nem igazán használok ilyet a gyakorlatban, úgyhogy ha valakinek van kedve írhat rá példát. Lehet, hogy pont ez lenne a jó megoldás amit keresek.
■ Ugyebár a relációs adatbázisok eredmánytáblát adnak vissza. Nem úgy, mint a FLWOR, az SQL képtelen hierarchiát (pontosabban az ehhez szükséges különböző egyedeket) egy eredménytáblában visszaadni. Érdekelne ki hogyan valósítja meg a hierarchikus logikát a lekérdezésekben. Itt van egykét megoldás amire gondolok, de mindegyiknek van valami kisebbnagyobb hibája.
A két tábla legyen "cikk" és "rovat". A "$where" pedig tételezzük fel, hogy valami közepesen bonyolult szűrő.
Egyesített query
Előny: egyetlen SQL lekérdezést kell csak értelmezni, végrehajtani, a MySQLnek.
Hátrány: nagy adatforgalom az adatbázis és a php között. Ha külön szerveren van az adatbázis, akkor még problémásabb.
$db->query("SELECT rovat.id AS rid, rovat.cim AS rcim, cikk.id AS cid, cikk.cim AS cid FROM cikk LEFT JOIN rovat ON rovat.id=cikk.rovat WHERE $where");
$utolsorovat = 0;
while ($rec = $db->fetch ()) {
if ($rec["rid"] != $utolsorovat) {
echo ('<div class="rovat">' . $rec["rcim"] . '</div>');
$utolsorovat = $rec["rid"];
}
echo ('<div class="cikk">' . $rec["ccim"] . '</div>');
}
Előny: nincs fölösleges adatforgalom, minden csak egyszer szerepel az eredményben.
Hátrány: Gyakorlatilag ugyanaz a query fut le kétszer. Nem tudom a MySQL mennyire tudja optimalizálni őket, kihasználja-e, hogy a WHERE igazsághalmaza ugyanaz a két lekérdezésben.
$db->query("SELECT rovat.id AS rid, rovat.cim AS rcim FROM cikk LEFT JOIN rovat ON rovat.id=cikk.rovat WHERE $where GROUP BY rovat.id");
$db2->query("SELECT rovat.id AS rid, cikk.id AS cid, cikk.cim AS ccim FROM cikk LEFT JOIN rovat ON rovat.id=cikk.rovat WHERE $where");
$utolsorovat = 0;
while ($rec = $db->fetch ()) {
if ($rec["rid"] != $utolsorovat) {
$rec2 = $db2->fetch ();
echo ('<div class="rovat">' . $rec2["rcim"] . '</div>');
$utolsorovat = $rec["rid"];
}
echo ('<div class="cikk">' . $rec["ccim"] . '</div>');
}
Biztos lehet így is, de én nem igazán használok ilyet a gyakorlatban, úgyhogy ha valakinek van kedve írhat rá példát. Lehet, hogy pont ez lenne a jó megoldás amit keresek.
SQL is tud hierarchiát
A FLOWR-t nem ismerem még, viszont az SQL is képes akár natívan is kezelni hierarchiát. Pl. Oracle esetén ott a
connect by
utasítás. Postgresql esetén is van egyconnectby
contrib csomag, illetve egy ugyanilyen célú, Oracle féle szintaktikát biztosító patch is.Ezenkívül van még többféle módszer is arra, hogy úgy tárolj fát adatbázisban, hogy egy lekérdezéssel ki tudd szedni a teljes (rész)fát a DB-ből. Pl. lásd Poetro cikkét, ami az adjacency list model nevű megoldást mutatja be. De létezik pl. path enumeration néven futó megoldás is, meg még egyéb lehetőségek is vannak.
Felhő
Ennél egyszerübb
http://www.fotexnet.hu/sid000000/page/category/039 (férfi cipők, gyermek cipők stb).
A kérdés csak annyi, hogyan lehet ezt elegánsan vagy a lehető legkevásbé bután csinálni.
Még 1 módszer
Másodlagos (id alapú) queryk
Előny: a $where szűrőit csak egyszer kell alkalmazni
Hátrány: Sok query fut le, minden szülőhöz (rovat) egy-egy önálló query-t kell értelmezzen az adatbázis.
esetleg group_concat
Felhő
kiróbálom...
Furcsálom, hogy egy ilyen (szerintem legalábbis) hétköznepi feladatra nincs bejáratott megoldás... :o
régebbi verziókban is van