Použití „related“ přes více 1:N relací
- koren
- Člen | 59
Ahoj. Snažím se přijít na to, jestli se skrz „related“ dá nějak chytře sáhnout až do tabulky „ob“ jednu relaci. Typickým příkladem může být vazba tabulek ve stylu „Univerzity > Fakulty > Studenti“, kdy obě vazby jsou 1:N. (každá univerzita má více fakult, každá fakulta má více studentů).
No a mě by zajímalo, jestli se dají nějak chytře vypsat všechny univerzity a ke každé všichni její studenti. Určitě by to šlo udělat trojitým foreach cyklem, ale mě zajímá, jestli by se nějak nedaly „přeskočit“ fakulty. Představuju si, že by to mohlo fungovat nějak takto:
<?php
{foreach $universities as $university}
{$university->name}
{foreach $university->related('faculty','universityId')->related('student','facultyId') as $student}
{$student->name}
{/foreach}
{/foreach}
?>
- romiix.org
- Člen | 343
Asi to nepôjde, keďže related()
sa volá na ActiveRow,
ale vracia GrupedSelection,
ktoré related()
nemá. Možno by nebolo odveci
implementovať to.
- Pavel Kravčík
- Člen | 1205
Pokud se těch závislostí nabalí příliš – zabiješ výkonnost.
Napadá mne:
- Studenti budou mít universityId (snadné volání všech studentů bez nutnosti šahat do tabulky fakulty).
- Napsat si na to přímo dotaz v SQL (tak to většinou řeším přes left joiny a nastavování aliasů, selectů a indexů → mnohonásobně vyšší výkonnost při velkých tabulkách).
- koren
- Člen | 59
Pavel Kravčík napsal(a):
Pokud se těch závislostí nabalí příliš – zabiješ výkonnost.
Napadá mne:
- Studenti budou mít universityId (snadné volání všech studentů bez nutnosti šahat do tabulky fakulty).
- Napsat si na to přímo dotaz v SQL (tak to většinou řeším přes left joiny a nastavování aliasů, selectů a indexů → mnohonásobně vyšší výkonnost při velkých tabulkách).
Ta výkonnost asi žádné terno nebude no :)
Varianta 1) mě napadla, ale nelíbí se mi na tom ten fakt, že pak by v databázi duplikovaly některé informace. Nakonec teda zřejmě sáhnu po 2).
Možná mě tedy spíš zajímá, jestli už náhodou není v Nette\Database nějaká zjenodušená funkce pro joinování (bez nutnosti psát vlastní SQL dotaz).
A ještě jedna otázka. Tu výkonnost zabíjí už samotný fakt, že jsou ty tabulky provázané, nebo až přílišné používání related()?
Editoval koren (12. 10. 2015 18:49)
- David Matějka
- Moderator | 6445
Možná mě tedy spíš zajímá, jestli už náhodou není v Nette\Database nějaká zjenodušená funkce pro joinování (bez nutnosti psát vlastní SQL dotaz).
->table('student')->where('faculty.universityId', $id);
- Pavel Kravčík
- Člen | 1205
koren napsal(a):
A ještě jedna otázka. Tu výkonnost zabíjí už samotný fakt, že jsou ty tabulky provázané, nebo až přílišné používání related()?
Nejsem žádný expert, ale jeden dotaz (i když velký) se provede rychleji
než 30.000 dotazů i když jednoduchých (lock, query, commit). Nejsem si
jistý, ale občas mi přijde že vypadne správné „selectování“, tj. se
tahá celá tabulky místo 1 sloupce, který je pak potřeba. Když si
nastavíš SELECT id,name
máš jistotu, že to bude rychlejší.
Ale třeba plácám nesmysly, hlouběji jsem to neřešil a na větší věci
opustil cykly s related().