Boj s vazbami M:N + cizi klice
- Duch.Veliky
- Člen | 68
Zdravím,
válčím trošku s tím jak správně používat dotazy používající vazby M:N. Už jsem konečně zprovoznil funkčí dotaz, akorát že mi to místo jednoho dotazu dělá 3 dotazy a to není úplně to, co by mělo.
TABULKA 1:
uzivatele_shopy
shop (int)
uzivatel (int)
- dva cizí klíče:
- shop (uzivatele_shopy.id na shopy.id)
- uzivatel (uzivatele_shopy.uzivatel na uzivatele.id)
TABULKA 2:
shopy
id (int)
nazev (varchar)
TABULKA 3
uzivatele
id (int)
jmeno (varchar)
Testovací dotaz mám:
<?php
$shopy = $this->database->table("uzivatele_shopy")
->where("uzivatel", $this->user->getId());
foreach ($shopy as $shop) {
echo $shop->ref("shop")->nazev;
}
?>
A místo aby to načetlo jenom jeden dotaz, tak to dělá:
1)
SELECT shop
, shopy
FROM uzivatele_shopy
WHERE (uzivatel
= 1)
2)
SELECT *
FROM uzivatele_shopy
WHERE (uzivatel
= 1)
3)
SELECT id
, nazev
FROM shopy
WHERE (id
IN (1))
Jako výsledek mi to vrátí, ale trochu divným způsobem :)
Editoval Duch.Veliky (10. 9. 2014 19:19)
- Mysteria
- Člen | 797
Ano, NDBT takhle funguje, místo jednoho JOIN dotazu udělá víc menších,
který jsou efektivnější.
Co se týká samotných dotazů, tak generovat by to mělo pouze dva – při
prvním spuštění 2 a 3 (protože neví, jaký sloupce budeš chtít tak *) a
při dalších 1 (protože už ví, jaký přesně data potřebuješ) a 3.
Editoval Mysteria (10. 9. 2014 19:23)
- David Matějka
- Moderator | 6445
Jestli chces vybrat vsechny shopy, co ma uzivatel, muzes pouzit tzv. „backjoin“, viz doc
- Duch.Veliky
- Člen | 68
Díky, kouknu i na ten backjoin.
@Inkode to jsem zkoušel původně taky, ale vracelo to
Nette\MemberAccessException
Cannot read an undeclared column ‚shopy‘.
A když jsem tam dal jenom $shop->shop->nazev, tak zase
Notice
Trying to get property of non-object
Funguje jenom ten tvar s tim ref() a ještě nevím proč, to teď zkoumám :)
- David Matějka
- Moderator | 6445
@Duch.Veliky kdybys mel ten sloupecek ve spojovaci tabulce pojmenovany
shop_id, fungovalo by i treba $vazba->shop->nazev
– pokud
se totiz nenajde sloupecek (shop) zkusi se NDBT kouknout, jestli neexistuje
sloupecek s FK, ktery tento retezec obsahuje (shop_id).
Pri soucasne strukture by ti tak melo fungovat treba
$vazba->sho->nazev
ale to radeji ten ref :)
Editoval matej21 (10. 9. 2014 19:34)
- Duch.Veliky
- Člen | 68
@matej21 jo máš pravdu, když tam dám „sho“, tak to funguje. Tak aspoň vím, jak to mám do budoucna pojmenovávat. Díky