Systém komponent a omezení počtu SQL dotazů

Kcko
Člen | 465
+
0
-

Ahoj,

hloubám nad touto věcí.

  • Jedna komponenta zobrazuje cosi.
  • Komponenta potřebuje data z DB a pro zjednodušení ji stačí udělat dotaz SELECT * FROM static_content where id = $id.
  • Komponent může být na dané stránce X, různě rozložené (hlavička webu, střed, patička …)

Co chci? Aby když na stránce vykreslím 10 komponent tohoto typu, aby se nevykonalo 10× dotazů s různými id ale jeden dotaz s klauzulí WHERE id IN (1,2,3... 10)

Zatím mě napadá mít ještě jednu nadřazenou kontrolku (něco jako „dohližitel“), do které dané kontrolky na dané stránce zaregistruji a pak na konci životního cyklu v konkrétním presenteru jim data donačtu.

Akorát se mi nelíbí interakce s presenterem a taky přesně nevím, do jaké akce životního cyklusu to dát, pravděpodobně beforeRender.

Nemá někdo nějaký nápad jak to elegantně vyřešit bez nějaké šílené objektové obludnosti?

Phalanx
Člen | 310
+
0
-

Můžeš obalit dotazy cache – https://doc.nette.org/cs/caching
Případně i celé komponenty…

Martk
Člen | 652
+
0
-

Kolik je záznamů v databázi a kolik očekáváš v budoucnu?

Kcko
Člen | 465
+
0
-

@Phalanx ano, ale to není to co jsem si představoval a popsal.
@Martk jsou to desítky, max lehké stovky

Jsou to vlastně statické bloky na stránce.

ZahorskyJan
Člen | 55
+
+2
-

Pokud je to 10 komponent na jedne strance a potrebuji to stejne, tak jim to predavame do tovarny jako vstupni parametr a je to priznana zavislost. U nas priklad: detail nejakeho zaznamu ma X komponent a kazde komponente do tovarny jde entita toho zaznamu. Bud pouzije jen tu entitu (0 dalsich dotazu do DB) nebo si vytahne jina souvisejici data. Druha moznost je sluzba/manager, ktera pri nacitani ty data cachuje do interni promenne pri prvnim nacteni. Tzn. dalsi nacteni jsou uz z interni promenne (0 opakujicich se dotazu). Vyhoda tady te sluzby je, ze neresis zivotni cyklus. Proste kdo ji zavola prvni ten polozi dotaz a ostatni uz nic. Nette/cache je na ti vetsinou zbytecna, musis resit invalidaci. Tady ta interni promenna plati jen na ten jeden beh/request.

Kcko
Člen | 465
+
0
-

@ZahorskyJan
S tebou popisovaných řešení se žádné nehodí.

  1. Je to komponenta s nějakým ID, takže jí žádnou smysluplnou entitu s daty nepřidám, komponenta si je má zjištovat sama.

A pokud si ty data tahá sama, tak jsme u toho co dělat nechci. 10 komponent = 10 dotazů.

  1. Služba / Manager, o tom se musí nějak dozvědět, jaké komponenty jsou na stránce. A už jsme u toho způsobu co mám v hlavě, ale pořád to není to pravé ořechové co chci, tj. to, že si nějaká dozorovací „observerve“ komponenta ty svoje „děti“ zaregistruje a pak jim na konci životního cyklu (už zná jejich ID) vytáhne a doplní data z DB.

A jinak co se týká kešování per request, to že by to zjistila první komponenta na stránce je taky k ničemu. Ta o svých kámoších podobného typu vůbec neví, neví tedy jaká ID má zjistit.

Chci mít prostě na stránce X komponent jednoduchého typu, každá pro svoje vykreslení potřebuje jiný řádek z DB, vzájemně o sobě neví a nechce se mi vymýšlet systém, který je bude nějakým způsobem registrovat / monitorovat a pak jim někde životního cyklu doplnňovat data, ale zatím je to to jediné smysluplné co mě napadá.

Editoval Kcko (7. 2. 2020 23:31)

ZahorskyJan
Člen | 55
+
0
-

@Kcko rozumim. Spatne jsem z dotazu, ze kazda ta komponenta ma jine zaznamy.

Pokud ty ID pro kazdou komponentu znas dopredu (podle ceho ho ty komponenty rozhoduji?), tak si udelej tu sluzbu s interni pameti, nacti jednim dotazem vsechny radky a uloz si hodnoty do pole, kde klic je ID. Z komponent pak volej sluzbu, aby ti vratila zaznam podle ID. Sahne do pameti a vrati. Muze byt fallback, kdyby se nenaslo, ze si dotaz polozi.

Pak je otazka, jestli 10 dotazu podle primarniho klice/indexu je opravdu problem a stoji za optimalizaci.

Kcko
Člen | 465
+
0
-

@ZahorskyJan

Rozumím, jediné co se může stát, že budu mít předpřipravený seznam komponent, které na stránce chci použít a pak třeba jednu – dvě z nějakého důvodu nebudu potřebovat (prostě ji v latte šabloně dočasně zakomentuji).

A hledám způsob jak sebrat IDčka pouze aktivních komponent na stránce a dodat jim data.

A to že se komponenta chce vykreslovat zjistím kde a jak? v render metodě? v attached? Tam by měla proběhnout nějaká kontrola a pak jí teprve dodat data, ale ty už musí být přednačtená onou servisou dopředu :-)

Jak tedy tohle vyřešit?

Martk
Člen | 652
+
0
-

To co by sis představoval nejde.

Že se komponenta použije zjistíš až v latte souboru, kde se provede kód {control foo}, to už je velmi pozdě a teprve v tuto chvíli se zavolá createComponentFoo. Shrnu to: teprve až se latte celé vyrendruje, tak znáš všechny komponenty.

Editoval Martk (8. 2. 2020 9:04)

Kcko
Člen | 465
+
0
-

@Martk
Chápu, nebyl jsem si zcela jistý, jestli je moje úvaha správná.
Ono bude asi ve finále jedno jestli se udělá dotaz WHERE id IN(1,2,3,4,5) a nakonec se použijí třeba jen první 3 komponenty.

Pořád lepší než 5 dotazů.

Nějak si s tím už poradím :-)