Přidat otázku mezi oblíbenéZasílat nové odpovědi e-mailem sql - skladání nebo jendotlivě

Ahoj, měl bych dva dotazy.

Potřebuju získat několik dat.
z tabulky 'clanky' potřebuju vše (ID, název, text, datum, id autora), informace o autorovi článku (ID, jméno, příjmení), rubriku (ID a název)

Mám toto všechno vybrat v rámci jednoho dotazu nebo mám dát každá zvlášt?
1. způsob:

'SELECT c.*, -- clanky
	u.jmeno, u.prijmeni -- uživatelé  
	r.ID as r_ID, r.nazev AS rubrika_nazev,  -- rubriky
LEFT JOIN uzivatele AS u ON c.uziatel = u.ID
LEFT JOIN rubriky AS r ON c.rubriky = r.ID
WHERE c.ID = ?';

2. způsob (vše jednotlivě):


$query = 'SELECT * FROM clanky WHERE ID = ?';
$stmt = $db->prepare($query);
...
$query = 'SELECT jmeno, prijmeni FROM uzivatele WHERE ID = ?';
$stmt = $db->prepare($query);

Z hlediska efektivity, co je lepší?

2. moje otázka.: Mám si do tabulky clanky taky přidat sloupec ID_rubriky nebo si vytvořit samostantou tabulkou (podobně jako u tagů kde to nemůžu dát rovnou do tabulky clanky, neboť každý článek může mít X tagu, kdežto jeden článek bude mít vždy jen jednu rubriku). Na ten sloupec bych dal index. Budu také vyhledávat články dle rubriky (proto nevím zda by nebylo lepší pro to udělat extra tabulku). Co je z hlediska efektivity lepší?

Děkuji za váš názor.

Předmět Autor Datum
ad dotaz1: Rychlejší bude samozřejmě metoda 2, ale výsledek bude pouhý dump obou tabulek na základě… nový
touchwood 22.10.2019 05:43
touchwood
pokud je to jen jedno pole, normalizovat není třeba, efekt je nulový. Pokud budu vybírat články jen… nový
ppavel1 22.10.2019 16:17
ppavel1
https://cs.wikipedia.org/wiki/Normalizace_datab%C3%A1ze nový
touchwood 22.10.2019 17:52
touchwood
Na otázky súvisiace s výkonom je väčšinou správna odpoveď: zmeraj si to a uvidíš. Určite nemá zmyse… nový
moose 22.10.2019 05:50
moose
Aha, díky. Měl bych ještě jeden dotaz ohledně indexů, zapomněl sem to napsat hned. Četl sem že index… nový
ppavel1 22.10.2019 16:44
ppavel1
Píšeš, že e-maily sú unikátne pre tvojich používateľov - tak daj unique index na email. Máš tých zá… nový
moose 22.10.2019 16:49
moose
Ne, nemám. Ale spíš mám k dispizi jen 1GB databázi a na druhým webhostingu jen 15MB. A když tam dám… nový
ppavel1 22.10.2019 17:37
ppavel1
Máš 1GB databázu a pýtaš sa čo sa stane pridaním indexu? To je dobrý vtip :) nový
pozorovateľ 22.10.2019 17:55
pozorovateľ
V případě, že databáze je správně navržena (indexy, cizí klíče, ...) a ty vracíš jeden záznam, pak j… nový
Jan Fiala 22.10.2019 07:05
Jan Fiala
A když načítam např. na hlavní stránce 10 příspěvků tak by byl jednodušší taky ten složený? nový
ppavel1 22.10.2019 16:27
ppavel1
Ano, jeden dotaz bude mít menší režii než několik jednotlivých dotazů poslední
Jan Fiala 24.10.2019 08:32
Jan Fiala

ad dotaz1:

Rychlejší bude samozřejmě metoda 2, ale výsledek bude pouhý dump obou tabulek na základě filtru pozičních parametrů, což je diametrálně odlišný výstup než je metoda 1.

ad dotaz2:
pokud je to jen jedno pole, normalizovat není třeba, efekt je nulový.

pokud je to jen jedno pole, normalizovat není třeba, efekt je nulový.

Pokud budu vybírat články jen z jedné rubriky tak bude přece lepší dát na ID_rubrika index. Nebo co jsi myslel tou normalizací? Index je nová tabulka, kdežto bez indexu by to museli vyhledávat řádek po řádku.

Na otázky súvisiace s výkonom je väčšinou správna odpoveď: zmeraj si to a uvidíš.

Určite nemá zmysel načítavať používateľov po jednom (edit: teda keď celkovo načítavaš viac článkov a viac používateľov), ale keď už z článkov vieš, akých používateľov budeš potrebovať, tak ti stačí druhá query pre načítanie potrebných používateľov (select where id in) a spojenie dát až na strane SQL klienta.

Na jednu stranu, jeden select dáva možnosť optimalizácie query na strane SQL servera, pri komunikácii máš len jeden request-response, SQL server parsuje query iba raz. Na druhú stranu jednotlivé SQL selecty dávajú viac priestoru na lepšie kešovanie, menej priestoru na zamykanie tabuliek, menej prenosu redundantných dát.

Nám vyšlo, že jednotlivé selecty boli pre náš prípad rýchlejšie.

K druhej otázke: Predpokladám, že keď budeš načítavať články, tak budeš vždy chcieť vedieť aj rubriku. V tom prípade ak budeš mať rubriku v tabuľke s článkom, tak sa pri ich selectovaní nebudú musieť spájať žiadne dáta (resp. maximálne dáta danej rubriky). Takže pri selecte článkov dajme tomu podľa dátumu pridania to bude rýchlejšie, ako keby SQL server ešte k tomu musel vyhľadávať z ďalšieho indexu, že v ktorej rubrike je daný článok.

Naopak, pri zobrazovaní článkov z danej rubriky, to je celkom jedno, pretože aj tak ideš podľa indexu s rubrika-článok a dáta článku sa dotiahnu z tabuľky s článkami. Či sú dáta indexu priamo v tabuľke s dátami alebo nie, už takú veľkú rolu nehrá (index si môžeš predstaviť ako samostatnú tabuľku). Ak ale potebuješ ešte usporiadať články z danej rubriky podľa času vytvorenia článku, tak má zmysel si do tej vedľajšej tabuľky ukladať aj ten čas vytvorenia a zahrnúť ho do indexu. Osobne by som to dal priamo do tabuľky s článkami.

Aha, díky. Měl bych ještě jeden dotaz ohledně indexů, zapomněl sem to napsat hned. Četl sem že indexy můžou ve výsledku zabrat vyce než celá tabulka. A když mám seznam registrovaných kde je Nick, email jak tam mám dát index? Když tam dám na unique na email, mohlo by to ve výsledku zabýrat hodně? Nebo bych mohl dát index např. jen na 5 prvních písmen. Na druhou stranu potřebuju zajistit že každá hodnota bude jiná. Kdybych dal index jen na prvních 5 písmen musel bych potom zamknout celou tabulku , následně najít zda se daný email už nevyskytuje a pokud ne tak bych mohl uživatele zaregistrovat. Jak bych to měl udělat?

V případě, že databáze je správně navržena (indexy, cizí klíče, ...) a ty vracíš jeden záznam, pak je lepší složený dotaz.
Server zpracovává jeden dotaz a vrací jeden záznam. Ty pak zpracováváš jeden dotaz.
Režie na několik dotazů bude vyšší.

Zpět do poradny Odpovědět na původní otázku Nahoru