database explorer – třídění podle počtu z druhé tabulky
- Allconius
- Člen | 317
Ahoj, mám tabulku anketa:
id, jmeno, kategorie_id, nominace, smazano
1, Pavel, 1, 1, 0
2, Petr, 1, 1, 0
3, Marek, 1, 1, 0
pak mám tabulku hlasovani:
id, anketa_id
1, 1
2, 1
3, 3
4, 3
5, 3
6, 2
potřeboval bych tu první tabulku seřadit sestupně podle počtu záznamu v té tabulce hlasovani tzn. Marek by měl být první, protože má 3 hlasy, Pavel má 2 a Petr jeden:
id, jmeno, kategorie_id, nominace, smazano
3, Marek, 1, 1, 0
1, Pavel, 1, 1, 0
2, Petr, 1, 1, 0
nějak v tomto smyslu:
$tabulka = 'anketa';
$tabulka1 = 'hlasovani';
$result = $this->database->table($this->tabulka)
->where(''.$this->tabulka.'.smazano = ?', 0)
->where(''.$this->tabulka.'.kategorie_id = ?', 1)
->where(''.$this->tabulka.'.nominace = ?', 1)
->order(''.$this->tabulka.'.kategorie_id ASC, COUNT('.$this->tabulka1.'.anketa_id) DESC');
jde to nějak ? Nebo je jednodušší si raději přidat do tabulky anketa další sloupec „pocet“ a ty hlasy si tam přepočítávat ?
- Polki
- Člen | 553
To je :D
Ale dotazy do databáze, třízení hodnotami z jiných tabulek atp. To jsou
věci co mají co dělat s databázemi ne s Nette.
Database Explorer je pouze prostředník, který to, co by si zapsal v SQL
jazyce můžeš přepsat do použití v Exploreru, čímž odstíníš
databázi.
Tedy když se naučíš SQL databáze, tak se rovnou naučíš i Nette Database
Explorer.
- Allconius
- Člen | 317
Polki napsal(a):
To je :D
Ale dotazy do databáze, třízení hodnotami z jiných tabulek atp. To jsou věci co mají co dělat s databázemi ne s Nette.
Database Explorer je pouze prostředník, který to, co by si zapsal v SQL jazyce můžeš přepsat do použití v Exploreru, čímž odstíníš databázi.
Tedy když se naučíš SQL databáze, tak se rovnou naučíš i Nette Database Explorer.
No sql umím ale nevím jak to přepsat do syntaxe nette database explorer, potřebuji udělat tento dotaz:
SELECT anketa.id, anketa.jmeno, anketa_hlasovani.anketa_id, COUNT(*) AS PROFCOUNT
FROM anketa
INNER JOIN anketa_hlasovani ON anketa.id=anketa_hlasovani.anketa_id
GROUP BY anketa_hlasovani.anketa_id
ORDER BY PROFCOUNT DESC
takže něco takového:
$result = $this->database->table($this->tabulka)
->select(''.$this->tabulka.'.jmeno, '.$this->tabulkahlasovani.'.anketa_id, COUNT(*) AS PROFCOUNT')
->where(''.$this->tabulka.'.smazano = ?', 0)
->where(''.$this->tabulka.'.kategorie_id = ?', $kat)
->where(''.$this->tabulka.'.nominace = ?', 1)
->group(''.$this->tabulkahlasovani.'.anketa_id')
->order('PROFCOUNT DESC');
akorát problém je že to vyhodí No reference found for $anketa->anketa_hlasovani protože mám referenci jen z té tabulky anketa_hlasování do anketa, ale opačně ne, takže asi jedině udělat jen výběr z anketa_hlasování, ale pak mi zas budou chybět jména, která dostala 0 hlasů
Editoval Allconius (18. 10. 2021 18:30)
- Polki
- Člen | 553
Tak nějak ti v tom tvém dotazu chybí sloupce smazano, kategorie_id a
nominace.
Taky nechápu, proč máš v selectu anketa.id
a
anketa_hlasovani.anketa_id
, když obsahují tu stejnou
hodnotu…
Taky děláš group, podle anketa_hlasovani.anketa_id
Proč?
Stačí podle anketa.id
ne?
Atd..
takže dobře je ten dotaz takto? :
SELECT `anketa`.`id`, `anketa`.`jmeno`, COUNT(`anketa_hlasovani`.`id`) AS PROFCOUNT
FROM `anketa`
LEFT JOIN `anketa_hlasovani` ON `anketa`.`id` = `anketa_hlasovani`.`anketa_id`
WHERE (`kategorie_id` = 1)
AND (`nominace` = 1)
AND (`smazano` = 0)
GROUP BY `anketa`.`id`
ORDER BY PROFCOUNT DESC
Jinak vše co potřebuješ máš v tom SQL dotazu:
$result = $this->database->table('anketa') // FROM anketa
->select('anketa.id, anketa.jmeno, COUNT(:anketa_hlasovani.id) AS PROFCOUNT') // SELECT `anketa`.`id`, `anketa`.`jmeno`, COUNT(`anketa_hlasovani`.`id`) AS PROFCOUNT a ta dvojtečka na začátku toho COUNT udělá: LEFT JOIN `anketa_hlasovani` ON `anketa`.`id` = `anketa_hlasovani`.`anketa_id`
->where('kategorie_id', 1) // WHERE (`kategorie_id` = 1)
->where('nominace', 1) // AND (`nominace` = 1)
->where('smazano', 0) // AND (`smazano` = 0)
->group('anketa.id') // GROUP BY `anketa`.`id`
->order('PROFCOUNT DESC'); // ORDER BY PROFCOUNT DESC
Jak vidíš, všechno je v tom SQL dotazu. Jak umíš SQL dotaz umíš
i Explorer.
Navíc je u exploreru nutné akorát vědět, že joiny se dělají tak, že
pokud je to relace hasOne tak je to klasicky přes tečkovou notaci a
pokud je to relace hasMany, tak je to přes dvojtečkovou notaci viz dokumentace.
Alternativně můžeš join dopředu vynutit pomocí alias metody, čímž se vyhneš používání dvojtečky a plného názvu celé druhé tabulky:
$result = $this->database->table('anketa') // FROM anketa
->alias(':anketa_hlasovani', 'hlasovani') // LEFT JOIN `anketa_hlasovani` `hlasovani` ON `anketa`.`id` = `hlasovani`.`anketa_id`
->select('anketa.id, anketa.jmeno, COUNT(hlasovani.id) AS PROFCOUNT') // SELECT `anketa`.`id`, `anketa`.`jmeno`, COUNT(`hlasovani`.`id`) AS PROFCOUNT
->where('kategorie_id', 1) // WHERE (`kategorie_id` = 1)
->where('nominace', 1) // AND (`nominace` = 1)
->where('smazano', 0) // AND (`smazano` = 0)
->group('anketa.id') // GROUP BY `anketa`.`id`
->order('PROFCOUNT DESC'); // ORDER BY PROFCOUNT DESC
EDIT 1:
Takže jak jsem psal myslím, že toto nebyl dotaz na Nette. Jak dělat join je
napsáno v dokumentaci, kterou si má člověk přečíst než začne
programovat a když dokážeš napsat SQL, tak dokážeš napsat i Explorer je
to intuitivní.
Editoval Polki (18. 10. 2021 21:40)
- Allconius
- Člen | 317
Polki napsal(a):
Tak nějak ti v tom tvém dotazu chybí sloupce smazano, kategorie_id a nominace.
Taky nechápu, proč máš v selectuanketa.id
aanketa_hlasovani.anketa_id
, když obsahují tu stejnou hodnotu…
Taky děláš group, podleanketa_hlasovani.anketa_id
Proč? Stačí podleanketa.id
ne?
Atd..takže dobře je ten dotaz takto? :
SELECT `anketa`.`id`, `anketa`.`jmeno`, COUNT(`anketa_hlasovani`.`id`) AS PROFCOUNT FROM `anketa` LEFT JOIN `anketa_hlasovani` ON `anketa`.`id` = `anketa_hlasovani`.`anketa_id` WHERE (`kategorie_id` = 1) AND (`nominace` = 1) AND (`smazano` = 0) GROUP BY `anketa`.`id` ORDER BY PROFCOUNT DESC
Jinak vše co potřebuješ máš v tom SQL dotazu:
$result = $this->database->table('anketa') // FROM anketa ->select('anketa.id, anketa.jmeno, COUNT(:anketa_hlasovani.id) AS PROFCOUNT') // SELECT `anketa`.`id`, `anketa`.`jmeno`, COUNT(`anketa_hlasovani`.`id`) AS PROFCOUNT a ta dvojtečka na začátku toho COUNT udělá: LEFT JOIN `anketa_hlasovani` ON `anketa`.`id` = `anketa_hlasovani`.`anketa_id` ->where('kategorie_id', 1) // WHERE (`kategorie_id` = 1) ->where('nominace', 1) // AND (`nominace` = 1) ->where('smazano', 0) // AND (`smazano` = 0) ->group('anketa.id') // GROUP BY `anketa`.`id` ->order('PROFCOUNT DESC'); // ORDER BY PROFCOUNT DESC
Jak vidíš, všechno je v tom SQL dotazu. Jak umíš SQL dotaz umíš i Explorer.
Navíc je u exploreru nutné akorát vědět, že joiny se dělají tak, že pokud je to relace hasOne tak je to klasicky přes tečkovou notaci a pokud je to relace hasMany, tak je to přes dvojtečkovou notaci viz dokumentace.Alternativně můžeš join dopředu vynutit pomocí alias metody, čímž se vyhneš používání dvojtečky a plného názvu celé druhé tabulky:
$result = $this->database->table('anketa') // FROM anketa ->alias(':anketa_hlasovani', 'hlasovani') // LEFT JOIN `anketa_hlasovani` `hlasovani` ON `anketa`.`id` = `hlasovani`.`anketa_id` ->select('anketa.id, anketa.jmeno, COUNT(hlasovani.id) AS PROFCOUNT') // SELECT `anketa`.`id`, `anketa`.`jmeno`, COUNT(`hlasovani`.`id`) AS PROFCOUNT ->where('kategorie_id', 1) // WHERE (`kategorie_id` = 1) ->where('nominace', 1) // AND (`nominace` = 1) ->where('smazano', 0) // AND (`smazano` = 0) ->group('anketa.id') // GROUP BY `anketa`.`id` ->order('PROFCOUNT DESC'); // ORDER BY PROFCOUNT DESC
EDIT 1:
Takže jak jsem psal myslím, že toto nebyl dotaz na Nette. Jak dělat join je napsáno v dokumentaci, kterou si má člověk přečíst než začne programovat a když dokážeš napsat SQL, tak dokážeš napsat i Explorer je to intuitivní.
Ahoj, ano, je to tak jak píšeš, potřebuju tam vlastně všechny pole z té tabulky anketa, takže takto:
SELECT anketa.*, COUNT(anketa_hlasovani.id) AS PROFCOUNT
FROM anketa
LEFT JOIN anketa_hlasovani ON anketa.id = anketa_hlasovani.anketa_id
WHERE (anketa.kategorie_id = 1)
AND (anketa.nominace = 1)
AND (anketa.smazano = 0)
GROUP BY anketa.id
ORDER BY PROFCOUNT DESC
no občas s tím mám trochu problém to přepsat do toho database exploreru hlavně při složitějším dotazu třeba s whereOr, díky moc za pomoc :-) Šéf zas bude mrkat jak jsem chytrej :-D
- Polki
- Člen | 553
Michal Kumžák napsal(a):
Jestli umíš sql, tak to napiš v něm, nemusíš používat explorer.
To není dobrý nápad. Budeš se opakovat, můžeš se zapomenout a být náchylný na SQL injection, nebo v neposlední řadě ztratíš přenositelnost modelu mezi jednotlivými DB systémy (MySQL, PostgreSQL, Sqlite atp.)
- Šaman
- Člen | 2667
Polki napsal(a):
Michal Kumžák napsal(a):
Jestli umíš sql, tak to napiš v něm, nemusíš používat explorer.
To není dobrý nápad. Budeš se opakovat, můžeš se zapomenout a být náchylný na SQL injection, nebo v neposlední řadě ztratíš přenositelnost modelu mezi jednotlivými DB systémy (MySQL, PostgreSQL, Sqlite atp.)
Proč? Nebude používat DbExporer, ale DbConnection. Všechny připomínky (kromě opakování) tím odpadnou, bude-li to napsané správně (proměnné se budou vkládat jako parametry, nikoliv nalepit přímo do stringu dotazu apod.) Opakování Explorer neřeší, to je zase věc modelu, aby ten specifický dotaz konala i na různým místech vždy stejná metoda.
Editoval Šaman (22. 10. 2021 18:29)
- Polki
- Člen | 553
Šaman napsal(a):
Polki napsal(a):
Michal Kumžák napsal(a):
Jestli umíš sql, tak to napiš v něm, nemusíš používat explorer.
To není dobrý nápad. Budeš se opakovat, můžeš se zapomenout a být náchylný na SQL injection, nebo v neposlední řadě ztratíš přenositelnost modelu mezi jednotlivými DB systémy (MySQL, PostgreSQL, Sqlite atp.)
Proč? Nebude používat DbExporer, ale DbConnection. Všechny připomínky (kromě opakování) tím odpadnou, bude-li to napsané správně (proměnné se budou vkládat jako parametry, nikoliv nalepit přímo do stringu dotazu apod.) Opakování Explorer neřeší, to je zase věc modelu, aby ten specifický dotaz konala i na různým místech vždy stejná metoda.
To je přesně to. ‚Pokud to nebude lepit dohromady‘ :D
Navíc ten dotaz není jednoduše rozšířitelný, musíš různě to sql
skládat a proč to dělat ručně, když to za tebe už pomocí
předpřipravených funkcí dělá explorer? :)
- Kamil Valenta
- Člen | 822
Samozřejmě se nabízí použít queryArgs(), takže riziko sql injection
odpadá. Přenositelnost mezi DB systémy je hezká vize, ale naplnitelná je
jen u jednodušších projektů.
Jsou dotazy, které jsou v queryArgs mnohem lépe čitelné, než
v exploreru.
- Polki
- Člen | 553
To je možná pravda, ale já takový dotaz ještě nenašel.
Na ani jednom projektu jsem ještě DbConnection nepoužil a nikdy nebyl
problém.
Naopak jsem přebral pár projektů, kde bylo DbConnection použito a muselo se
to s implementací nových funkcí komplet předělávat, takže jsem spíše
zastánce Exploreru, pokud se používá databáze, kterou Explorer umí.
- Kamil Valenta
- Člen | 822
Polki napsal(a):
To je možná pravda, ale já takový dotaz ještě nenašel.
Například všechny selecty ze stored procedures (pokud se něco nezměnilo
v Nette 3.x).
Tam explorer vůbec použít nejde, protože si odnikud nezíská strukturu
„tabulky“.
Editoval Kamil Valenta (23. 10. 2021 22:38)
- Polki
- Člen | 553
Kamil Valenta napsal(a):
Polki napsal(a):
To je možná pravda, ale já takový dotaz ještě nenašel.
Například všechny selecty ze stored procedures (pokud se něco nezměnilo v Nette 3.x).
Tam explorer vůbec použít nejde, protože si odnikud nezíská strukturu „tabulky“.
Tak tam je potom otázka, jestli chceš přenášet logiku dotazování do databáze, nebo jestli to chceš dělat na straně serveru. Jako nikdy jsem stored procedures nepoužil, ale řekl bych, že cokoliv, co obsahuje stored procedure můžeš napsat pomocí Exploreru a tedy stored procedures nepoužiješ.
Na druhou stranu rozumím, že použít stored procedures bude někdy rychlejší. Například když se dělá více dotazů za sebou, tak je udělám rovnou v databázi, aniž by se musely dělat třeba 4 dotazy ze serveru. Nicméně tento princip, kdy se zavolá nějaká funkce z databáze, která toho udělá více naráz jsem nejednou slyšel označený jako špatný, jelikož databáze potom může udělat na pozadí nějaké nečekané změny, se kterými ty v aplikaci nemusíš počítat, proto by měla prý všechna práce s daty probíhat na jednom místě a tedy ideálně na serveru.
Reálně jsem použil jen view, se kterým si Explorer poradí. No a pokud dodržuješ to, co většinou lidi doporučují (jen 1 jsem slyšel říkat opak) a to, že DB je jen něco jako kartotéka, kam se ukládají data a logika pracování s nimi by měla být na straně serveru, tak ti Explorer dokonale vyhovuje.
- Kamil Valenta
- Člen | 822
Obávám se, že máš dost zúžený pohled jen tím, s čím jsi se
setkal. A znovu se vracím k tomu, že ano, na jednodušší databázově
věci explorer stačí.
Pokud jsi nikdy nepoužil stored procedures, tak to není úplně nejlepší
předpoklad pro to hodnotit, zda jsou v návrhu databáze dobře nebo chybou,
že?
Mohou vytvářet databázové API, mohou zajišťovat integritu dat. Při
používání proměnných mohou být naprosto nepostradatelné (u pohledů
třeba).
Tvá statistika říká, že jsi asi nemluvil s lidmi, kteří pokročilé
nástroje DB potřebují.
Také si protiřečíš, když chceš vše vykonávat na straně serveru, ale
webová aplikace je pouze clientem. Navíc dost možná jedním z mnoha. Takže
to riziko chybovosti naopak rozprostíráš a hledej pak, který client
v datech udělal bugr. Dost možná web, dost možná cokoliv jiného…
- Polki
- Člen | 553
Kamil Valenta napsal(a):
Obávám se, že máš dost zúžený pohled jen tím, s čím jsi se setkal. A znovu se vracím k tomu, že ano, na jednodušší databázově věci explorer stačí.
Pokud jsi nikdy nepoužil stored procedures, tak to není úplně nejlepší předpoklad pro to hodnotit, zda jsou v návrhu databáze dobře nebo chybou, že?
Mohou vytvářet databázové API, mohou zajišťovat integritu dat. Při používání proměnných mohou být naprosto nepostradatelné (u pohledů třeba).
Tvá statistika říká, že jsi asi nemluvil s lidmi, kteří pokročilé nástroje DB potřebují.
Také si protiřečíš, když chceš vše vykonávat na straně serveru, ale webová aplikace je pouze clientem. Navíc dost možná jedním z mnoha. Takže to riziko chybovosti naopak rozprostíráš a hledej pak, který client v datech udělal bugr. Dost možná web, dost možná cokoliv jiného…
- Nehodnotím, jestli je to dobře nebo ne :D Je to jako kdybych ti řekl, že jako zdroj vitamínu C nejím citrony, ale pomeranče a ty jsi mi na to oponoval, že to, že já nejím citrony přece neznamená, že jsou citrony špatné. No neznamená a nikdy nikdo nic takového neřekl. Myslel jsem, že dobří programátoři právě tohle chápou, protože jsou schopni komunikovat s PC, který si taky neumí domýšlet věci, takže vše je přesně tak, jak jsem napsal nic víc, nic míň.
- Ohledně toho, s čím jsem se setkal je dost možné, že jsem měl prostě jenom smůlu. Nicméně jelikož statistika říká, že pro 10 milionů jednotek s 3% neúspěšností stačí 1100 testovacích subjektů. No a jelikož na světě je prý aktuálně něco kolem 400K SW firem, tak si myslím, že moje statistika více než 9000 firem různě po světě je zatím dostačující (Stará 3 roky a podle odhadů by prý v roce 2027 mělo být 1mega SW společností, takže statistika snad ještě nějakou chvíli bude platit :D )
- Na databázové API stejně budeš dělat server. Nebudeš se nikdy připojovat napřímo k databázi třeba z android aplikace… Moc tady nechápu tenhle argument.
- Pokud máš opravdu potřebu cpát nějaké algoritmy do pohledů, tak je to úplně jedno, protože s pohledy si Explorer poradí a to jak se ten pohled na pozadí vytvoří, jestli jen nějakým selectem, nebo na to máš proceduru nikoho nezajímá.
- Pokud potřebuješ řešit integritu dat, tj. bez jejich změn, tak na to můžeš využít trigger, který se spustí před vkládáním do tabulky a v případě neshod vyhodí Error. V takovém případě Opět z aplikace nepotřebuješ umět pracovat se StoredProcedures. Navíc integritní triggery málokdy potřebují cyklus/proměnnou atp.
- Chápu, že jsi mi chtěl ukázat, že ty stored procedures jsou potřeba, ale není to tak úplně pravda. Ohledně integrity dat to si může jednoduše ověřit už aplikace a taky to dělá a doporučuje se to, aby se nedělal zbytečně dotaz do databáze, pokud data nesedí. To znamená, že dělat to ještě jednou v databázi je cesta do pekla, jelikož kdykoliv se něco změní, tak to budeš dělat na více, než 1 místě. Na to, aby se ti do DB po síti dostaly ok data z aplikace existují zabezpečené přenosové protokoly, které neodchytíš/nerozluštíš, takže databáze si může být jistá, že dostane validní data, tedy tento problém odpadá. Pokud by si namítal opak, tak kdybych neměl zabezpečené spojení mezi serverem a databází, tak je úplně jedno, že děláš nad databází ověření integrity, jelikož když ti někdo odchytí komunikaci, tak si ji může změnit na nějaký krásný svůj SQL kód, který třeba vypíše hesla a celá integrita na straně databáze ti stejně je k prdu. No a když jde o pohledy, tak tam taky potom záleží, jaký DB systém používáš. Dělat pohledy třeba nad MySQL/MariaDB a ještě se stored procedurama je nerozum, protože se to stejně spustí vždy znovu, takže pak je jedno, jestli to máš na straně databáze, nebo na serveru. No a jelikož je MySQL/MariaDB nejrozšířenější DB systém, tak asi máme jasno. :) Jediná výjimka je snad kdyby jsi těch dotazů měl několik a potřeboval z nich vycucnout data a přišlo by ti líto dělat N dotazů. Ale to je taky ojedinělé. Stejně všechno cachuješ :)
ale webová aplikace je pouze clientem
WTF? Co je tohle za nesmysl.. :D Jako jo, chápu, že chceš říct, že server je ten, kdo odpovídá a klient ten, kdo se dotazuje, ale tohle dogma ti nabourává třeba Peer2Peer spojení, kde žádný server není… :D Možná by to chtělo ‚Back to school‘. Záleží dost, kde se pohybuješ. Jestli web Appka, tak ta může klidně vypadat tak, že existuje Tenký klient, Tlustý klient a mobilní aplikace. No a všichni tito ‚klienti‘ se dotazují pro data kam? No na nějaké API. A co to API dělá? Dotazuje se na data do Databáze. A co je to WEB aplikace? No Tenký klient, který se dotazuje na SERVER a SERVER se pak dotazuje na DATABÁZOVÝ SERVER. Tzn., že SERVER je aplikace někde na nějakém PC, která je co? No nějaké API, které na určitý požadavek vrátí určitou odpověď. No a jestli je ta odpověď v HTML, nebo XML, nebo JSONu, CSV atp. a do kterého dalšího klienta data jdou, tak to je z hlediska architektonického návrhu úplně jedno. Stejně tak, pokud máš vícero serverových částí z nějakého mě neznámého důvodu, tak od toho, aby jsi neměl na vícero různých serverech zduplikovaný ten stejný kód, tak vzniklo co? Hádáš správně MICROSERVICES. Takže je úplně jedno, kolik reálných klientů mám. Každý z nich, který pracuje s daty, potřebuje nějaké API, které jim ta data poskytne. To znamená, že na práci s databází mám vždy 1DB server a 1API v Nette, které se na ten DB server dotazuje a distribuuje data dál. Buď přímo mobilní aplikaci/tlustému klientovi, nebo nějakému jinému serveru, který pak na tenkého klienta posílá HTML kód atp. A pokud budeš chtít namítnout, že Clustery… Tak si to zase můžeš zastrčit do argumentovacího šuplíku, jelikož Clustery se řeší tak, že na všech ideálně běží docker/whatever, který se aktualizuje z GITu pomocí webhooků a tedy vše, co se pushne na určitou větev gitu se automaticky deployne na všechny clustery s tím, že je možné ještě server, který se stará o přerozdělování prostředků o tom informovat a ten bude čekat na zprávy od jednotlivých uzlů o dokončené aktualizaci a bude přerozdělovat požadavky jen na ty už aktualizované. Tedy z venku se Cluster bude jevit jako 1 server.
Já doufám, že jsem napsal všechno a snad z toho jde vidět, že i na obří aplikace, které musí běžet na různých zařízeních, propojují se s dalšími dceřinými aplikacemi a jsou pro load balancing rozdělené do clusterů bohatě stačí Explorer a že si fakt neprotiřečím.
Editoval Polki (25. 10. 2021 11:53)
- Šaman
- Člen | 2667
@Polki: Celé tohle začalo tvým příspěvkem, že nepoužívat
DbExplorer a psát přímo $dbConnection->query()
není dobrý
nápad. S čímž, za určitých podmínek, také nesouhlasím. Explorer je
fajn na mnoho věcí, ale viděl jsem (v praxi) dotazy na půl A4 a přepisovat
je do Exploreru by bylo peklo. Navíc SQL je v takhle složitých dotazech
lépe čitelné.
Koneckonců proto jsou v Nette obě varianty (čistá
Connection
i chytrý Explorer
).
- Kamil Valenta
- Člen | 822
Jistě, navíc je celá řada dotazů, které nepracují nad žádnou tabulkou a pak je pro ně explorer z principu nepoužitelný a query[Args]() je správná volba.
- Polki
- Člen | 553
@Šaman Buď špatně napsaný SQL, nebo je člověk začátečník.
Navíc určitě obsahem toho SQL dotazu byly kousky kódu, které se vyskytují
i v jiných SQL dotazech, takže mít to jako čisté QUERY nedává moc
smysl. No a Connection
existuje, protože jej využívá
Explorer
, čímž se z Exploreru stává ta mezivrstva, kterou si
každý, kdo používá Connection
stejně píše sám.
Explorer je takový Builder databázového dotazu, kde metoda
->fetch*
zapříčiňuje, že se seskládá to query a pak to
query vykoná už samotná Connection. Tedy není v Nette
Connection
proto, že by bylo nezbytné pro práci, ale proto, že
jej interně využívá Explorer
. Tak to platí i u více
knihoven.
Pokud by byl dotaz napsaný dobře, člověk by dobře napsal strukturu
buildění dotazu explorerem a vše si správně nazval, tak nevidím žádnou
výhodu použití čistého SQL i kdyby přes Connection
. Vždy to
bude přehlednější pomocí Exploreru, protože jednotlivé části buildu
můžeš krásně od sebe oddělit a stanou se znovupoužitelnými.
BTW: Explorer mi kolikrát taky vygeneruje dotaz o 30 řádcích, ale
v kódu v exploreru ho mám zapsanej na 5 třeba a myslím, že co má méně
řádků je přehlednější ostatně jak píše samo Nette. ‚Less code more
SECURITY‘
@KamilValenta o tom to právě je… Databázi na začátku nastavíš a pak ji využíváš jako ‚úložiště dat‘ Už podle názvu ‚DataBase‘ veškerá ostatní logika je pak na straně serveru, ne databázového serveru, díky čemuž se práce s databází smrskne na jednoduché CRUD operace, díky čemuž je jednodušší manipulace s daty a cachování. No a na to už díky abstrakci dotazů a pokládání efektivních dotazů je Explorer dokonalá volba.
Chápu, že každý máme k práci s db svůj přístup a jako u náboženství ten náš je ten správný a každý je myslím dost chytrý, ab si svou cestu vybral sám, takže si myslím, že bychom to mohli ukončit co hoši.
Editoval Polki (26. 10. 2021 16:44)
- Kamil Valenta
- Člen | 822
Je celá řada dotazů, které nepracují nad žádnou tabulkou a pak je pro
ně explorer z principu nepoužitelný a query[Args]() je správná volba.
Můžeš se kolem toho rozepisovat jakkoli rozsáhle, ale pokud jsou v aplikaci
dotazy, které explorerem do db nepošleš (v našich projektech např. ve
všech), pak na Tvou hru nikdo přistoupit nemůže.
Editoval Kamil Valenta (26. 10. 2021 21:26)
- Polki
- Člen | 553
Je celá řada dotazů, které nepracují nad žádnou tabulkou a pak je pro ně explorer z principu nepoužitelný a query[Args]() je správná volba.
Pravda, ale nikdo tě nenutí je používat.
- Tabulky si můžeš vytvořit dopředu, tedy příkazy na tvorbu/alter tabulek nepotřebuješ.
- Truncate odporuje zásadám zachování dat, kdy by se jen měl nastavit příznak neviditelnosti.
- Nastavování znakové sady atp. není třeba, jelikož to Nette dělá samo.
- Volání/tvorba/editace/mazání uložených procedur není třeba, jelikož jejich logika se přenese mimo DB
atd. Tak můžu pokračovat u každého dotazu, který není CRUD operace nad tabulkou. Jediná výjimka je migrace databáze, ale na to snad každý používá nějakou migrační knihovnu, která to řeší za něj.
To je jako by jsi propagoval, že zabít souseda, protože s ním máš neshody je v pohodě, že to tak děláte u každého a je to reálná možnost, která existuje a kdyby se to používat nemělo, tak by přece zabíjení neexistovalo… A někomu, kdo ti bude říkat, že se to dá vyřešit i mírumilovnou cestou by si říkal, že to nejde.
Můžeš se kolem toho rozepisovat jakkoli rozsáhle, ale pokud jsou v aplikaci dotazy, které explorerem do db nepošleš (v našich projektech např. ve všech)
To, že vy to neumíte/nechcete dělat jinak neznamená, že to nejde. My naopak v našem týmu máme za sebou přes 800 udržovaných projektů různých velikostí (a více než 50% i mezinárodních), mezi kterými jsou například i E-shopy (včetně redesignu E-shopů z Shoptetu) s napojením na různé CRM, účetnictví, mobilní appky, evidence skladů, objednávkový systémy, řídící systémy strojů v továrnách/skladech, chytré domácnosti, IoT a tuny dalších věcí a hádej jak často jsme museli použít dotaz, který nepracuje s tabulkou pomocí CRUD operací a tedy něco jiného, než Explorer? NIKDY
Takže to není o nějaké mojí hře, ale o tom, jestli člověk umí, chce a je dost chytrý.
- Kamil Valenta
- Člen | 822
Už mne to s Tebou moc nebaví pro Tvou útočnost, ale budu ignorovat tu omáčku okolo a půjdu čistě po faktech.
Pro potřeby logování pomocí triggerů posíláme do db sessiony ID přihlášeného uživatele pomocí dotazu:
SET @uzivatele_id=n
Jak to prosím zapíšeš pomocí exploreru?
Formuláře generujeme mapováním na strukturu db tabulky, využíváme dotazy typu:
SHOW FULL COLUMNS FROM table
Jak to prosím zapíšeš pomocí exploreru?
Stored procedures jsou často využívány jako API na vzdálené databázi, kterou dostaneme a máme práva volat jen procedury. Máme klientovi říct „víte, my ty procedury volat nebudeme, protože jsme chytří, chceme a umíme“?
U synchronizace používáme dotazy:
REPLACE INTO table...
Jak to prosím zapíšeš pomocí exploreru?
Logování do partitionovaných tabulek podle roku probíhá při neexistenci tabulky s voláním dotazu:
create table log_' . date('Y') . ' like log_matrice
Jak to prosím zapíšeš pomocí exploreru?
Prosím, nepiš mi žádná přirovnání ani výčty na čem všem jsi dělal a s kým jsi mluvil. Pošli mi prosím uvedené dotazy přepsané do exploreru, ať vidím, jak to máme dělat správně. Děkuji.
- Kamil Valenta
- Člen | 822
@Polki potvrď celou tuto vleklou diskuzi tím, že ukážeš, jak uvedené a potřebné dotazy zapíšeš pomocí exploreru. Jsem přesvědčen, že ty dotazy jinou sekvencí dotazů nenahradíš, ale nebráním se ani tomu. Máš teď možnost ukázat v praxi, o čem jsi nás přesvědčoval.
- Mysteria
- Člen | 797
Hádej jak často jsme museli použít dotaz, který nepracuje s tabulkou pomocí CRUD operací a tedy něco jiného, než Explorer? NIKDY
Tohle je ale přece úplně špatně. Je jasný, že i kdybys napsal milion aplikací, tak když je záměrně píšeš tak, abys nemusel nic jiného než CRUD používat, tak v nich pak logicky nic jiného používat nemusíš.
- Polki
- Člen | 553
@KamilValenta nemám sílu to s tebou řešit. jako příklady píšeš naprosto nesmyslné věci, které se jenou vymstí jak tobě, tak tomu zákazníkovi, který vám zpřístupní jen DB se stored procedures. Už chápu, proč se aplikace běžně tvoří rok, když je možné je mít hotové za týden. Nicméně pokud vám to tak vyhovuje a nemáte problém zahodit tunu času a peněz za složité řešení, které do budoucna má potenciál selhat a musíte to pak přepisovat, obcházet aby to sedělo, tak proč ne. Vaše volba. Učit tě jak na to správně nebudu od toho dělám školení. :) Můj čas je na rozdíl od vašeho jak tak koukám cenný. :)
@Mysteria To je přesně to, jak jsem to myslel. Jsem rád, že to alespoň někdo pochopil :) Je pěkné vidět, že i dnes existují programátoři, kteří čtou, co se píše a přemýšlí nad tím, takže situaci chápou. Nikdy jsem totiž nenapsal, že dokážu napsat jakýkoliv dotaz do databáze v exploreru, ale že dokážu navrhnout databázi a aplikaci tak, aby nic jiného, než CRUD operace nad databází nebyly nutné. Proto mě zaráží, že někteří mají asi klapky na očích a pořád melou jak by si teda explorerem zapsal tento dotaz? No nijak :D Protože ho vůbec nemusím použít. :D Ještě jednou díky za to, že jsi ukázal, že jsem se nerozepisoval zbytečně a jsou lidi, co to chápou. :)