Autor Zpráva
BunnyBugs6
Profil *
Ahoj, mám dotaz, už po tom pátrám asi týden a pořád nevím, jak na to :(
Nevím, jak udělat odkaz v pravém menu na výpis z databáze.
Mám stránku index.php, kde mám hlavní rozvržení a pomocí php se mi tam vkládá hlavní stránka s obsahem (cont-col.php) a vpravo menu (right-col.php). V hlavním obsahu se mi načítá obsah z databáze pomocí příkazu
$vysledek = mysql_query("SELECT * FROM `$table` WHERE `id_vyjezd` = '$vyjezd' LIMIT 1,100");
Potřebuji v pravém menu vytvořit odkazy na určité výpisy z databáze a to tím způsobem, že pomocí odkazu se mi změní ta hodnota $vyjezd.
V klasickém php tvořím odkazy takto:
<a href="?show=cont-col&colr=right-col">ODKAZ1</a><
ale prostě nevím, jak vytvořit jednotlivé odkazy, aby mi vypsal jen určitou část tabulky do té hlavní stránky (cont-col.php), resp. odkaz by pouze změnil v hlavní stránce proměnou $vyjezdy.
Dokážete mi s tím někdo poradit? Díky moc.
Destiny_1
Profil
Proměnnou $vyjezd lze získat pomocí odkazu jednoduše takhle:
if(isset($_GET['right-col']))
{
$vyjezd = mysql_real_escape_string($_GET['right-col']);
}
Pak bude odkaz vypadat například takhle.
<a href="?show=cont-col&right-col= tady bude hodnota id_vyjezd ">ODKAZ1</a>
BunnyBugs6
Profil *
Super, děkuji moc, to funguje :)
Mám k tomu ale ještě jednu otázku. Nastavil jsem tam ještě else, asi nějak takto:
if(isset($_GET['right-col'])) {
        $vyjezd = mysql_real_escape_string($_GET['right-col']);
        }
        else $vyjezd = "něco";
to znamená, že mi to při prvotním načtení stránky vypíše kus z tabulky dle parametrů "něco".
Jak ještě do toho else dostanu, aby se mi prvotní stránka načítala vždy ta nejbližší k aktuálnímu datu, abych to pokaždé nemusel ručně přepisovat?
Např.: teď v tom "něco" mám ručně vypsáno nejbližší datum konání akce třeba 3.1., po tomto datu to už nebude aktuální a chtěl bych, aby se mi od skončení tohoto data vypisovala automaticky nová akce, která bude třeba až 10.1. Prostě aby to automaticky vypisovalo vždy aktuální nejbližší akci, která je vždy v úplně jiné datum.
Mockrát děkuji za pomoc.
juriad
Profil
Polož ještě jeden dotaz na nejbližší akci a vráceným id naplň proměnnou $vyjezd ve větvi else.
SELECT id FROM `$table` WHERE datum > NOW() ORDER BY datum ASC LIMIT 1
BunnyBugs6
Profil *
juriad:
Jsem asi tupej, ale já fakt nevím jak, šlo by to prosím nějak konkrétněji?, já se to teprve učím a ještě mi to moc nejde :( děkuji.
BunnyBugs6
Profil *
juriad:
Pořád v tom tápu a nevím. Napsal jsem to takhle:
$aktual = mysql_query("SELECT `id_vyjezd` FROM `$table` WHERE `datum_kon` > NOW() ORDER BY `datum_kon` ASC LIMIT 1");
    
    if(isset($_GET['right-col'])) {
        $vyjezd = mysql_real_escape_string($_GET['right-col']);
        }
        else $vyjezd = ($aktual['id_vyjezd']);
Vůbec netuším, kde je chyba :( Když to zkusím v samostatné stránce, tak to tu správnou hodnotu vypíše, ale pokud to chci dosadit za tu proměnou $vyjezd, tak to prostě nefunguje :(


Už jsem na to přišel, po dlouhém trápení, ale tím se aspoň něco naučím. Tak snad to mám takhle správně:

else 
            while($test = mysql_fetch_array($aktual)) {
            $vyjezd = mysql_real_escape_string($test['id_vyjezd']);
            }

Jinak moc díky za rady :)
anonymníí
Profil *
BunnyBugs6:
- cyklus while je zbytečný, když je tam 1 řádek
- SQL dotaz volej až v té else větvi, ať ho nevoláš zbytečně vždy
BunnyBugs6
Profil *
Opravdu funguje, je to super, ale mám s tím spojený ještě jeden dotaz, na který jsem v průběhu narazil.
Pro jistotu vypisuji celý kód:

$aktual = mysql_query("SELECT `id_vyjezd` FROM `$table` WHERE `datum_kon` > NOW() ORDER BY `datum_kon` ASC LIMIT 1");
    
    
    if(isset($_GET['right-col'])) {
        $vyjezd = mysql_real_escape_string($_GET['right-col']);
    }
        else
            while($test = mysql_fetch_array($aktual)) {
            $vyjezd = mysql_real_escape_string($test['id_vyjezd']);
            }

To první IF mi dělá odkazy v pravém menu, ELSE mi zaručuje při spuštění načtení aktuální nadcházející události, ale v případě, že všechny události už jsou prošlé, zobrazí mi to chybu, protože nemůže nic najít. Jak v tomto případě do toho dostanu ještě podmínku, že pokud existuje nová událost, ať ji zobrazí, v opačném případě ať zobrazí tu poslední prošlou?, nebo lépe nějakou jinou stránku?
Už jsem zkoušel zase pár věcí, ale nevím, jak to do toho přesně dostat. Díky za radu.
juriad
Profil
if (isset($_GET['right-col'])) {
  $vyjezd = mysql_real_escape_string($_GET['right-col']);
} else {
  # ten dotaz na následující pokládej jen když musíš (tedy až v else)
  $nasledujici = mysql_query("SELECT `id_vyjezd` FROM `$table` WHERE `datum_kon` > NOW() ORDER BY `datum_kon` ASC LIMIT 1");
  # jelikož víš, že dotaz vrátí nula nebo jeden řádek, tak stačí if
  if($test = mysql_fetch_array($nasledujici)) {
    $vyjezd = mysql_real_escape_string($test['id_vyjezd']);
  } else {
    $vyjezd = false;
  }
}

# ted je $vyjezd buď platné ID, nebo false

if($vyjezd !== false) {
  # normálně vypiš jako dosud
} else {
  echo "Není žádná další naplánovaná hdálost";
}
BunnyBugs
Profil *
Zdravím, mám ještě jednu prosbičku, s kterou si nevím rady a souvisí to přímo tady s tou situací:
Mám volání z databáze jak uvedeno v prvním příspěvku, tedy:

$vysledek = mysql_query("SELECT * FROM `$table` WHERE `id_vyjezd` = '$vyjezd' LIMIT 1,100");

dál je z toho volán odkaz (jak tady řešeno) na proměnnou $výjezd, to je vše v pořádku a funguje, mimochodem ještě jednou děkuji, ale teď bych potřeboval, aby součástí toho odkazu byla měněna ta proměnná na výběr tabulky, tedy proměnná $table? Potřebuji totiž oddělit sezóny tak, aby každá sezóna byla v samostatné tabulce (tj. každý rok nová), protože jinak by v jedné tabulce bylo strašně moc záznamů. Do teď to bylo jednoduché, jedna tabulka, nastavení proměnné $tabulka na pevno, ale když teď budou tabulky dvě, pak tři, čtyři, atd? Když změním tu proměnnou $table na novou tabulku, přestanou mi historie, tedy stávající odkazy, které bych rád zachoval k nahlížení.

Děkuji moc za jakékoliv řešení.
juriad
Profil
BunnyBugs:
Všechny sezóny měj v jedné tabulce. Co znamená hodně záznamů, miliony? Pokud ne, databáze to v pohodně zvládne, zvládne i víc.
Pro zvýšení výkonu přidej index na sloupec id_vyjezdu, pokud už tam není. Pokud tam máš klíč, není co řešit.
Obdobně můžeš prostudovat i další selecty a doplnit indexy na sloupce, které jsou v podmínkách.

Naopak z rozdělování souvisejících záznamů do více tabulek plynou jen problémy: co když budeš chtít nějaké záznamy vypisovat bez ohledu na sezónu?

Pro porovnání: toto skoro deset let staré fórum obsahuje 961243 příspěvků (všechny jsou uloženy v jediné tabulce). Přijde ti toto fórum svižné?
bunnybugs
Profil *
Aha, tak to je potom jiná. Někde jsem četl, že čím více záznamů, tím pomalejší, to je logické, ale při mých zhruba desetitisících záznamů za rok, to pak ztrácí jakýkoliv význam. No, tím jsem si mohl ušetřit tu proměnou $ table, ale to už je teď jedno.
Díky za komentář, jen mi není úplně jasné, jak a k čemu je dobrý ten index či klíč. Sice jsem to četl, ale nějak jsem nepochopil výhodu. Mohu poprosit o stručné vysvětlení výhod a použití? Díky.
Tori
Profil
bunnybugs:
k čemu je dobrý ten index či klíč
Dám příklad - máte tlustou knížku, třeba dějiny literatury od Sumeru po Karla Maye, a chcete zjitit, kde všude se zmiňuje např. Gilgamešův epos. Buď můžete prolistovat celou knihu stránku po stránce, anebo se podívat na konec knihy do věcného rejstříku, kde zjistíte přesně čísla stránek. Druhá varianta je samozřejmě rychlejší. A v podstatě stejně to funguje, když DB hledá nějaký záznam na sloupci s indexem nebo bez něj.
Tohle se týkalo běžných + fulltextových indexů. Pak jsou ještě unikátní klíče (nebo indexy), kterými zajistíte, že se v tom sloupci nebudou opakovat hodnoty (např. uživatelské jméno), a primární klíč - což je unikátní index, který jste si vybral, že podle něj budete identifikovat jednotlivé řádky/záznamy v tabulce. V tabulce může být unikátních identifikátorů několik - např. v tabulce uživatelů/lidí můžete jednotlivé uživatele jednoznačně identifikovat podle rodného čísla, loginu i podle automaticky generovaného ID – ale jako primární klíč smíte zvolit jen jeden z nich.
juriad
Profil
Obyčejný index nad jedním sloupcem umožňuje extrémně rychlé vyhledávání.
Obvykle se k tomu používá datová struktura strom, který umožňuje vyhledat číslo (pro něj se to snadno představuje, ale funguje to i s čímkoli jiným) za pomoci log(n) porovnání, na rozdíl od tupého prohledávání všech n záznamů.
V případě miliony záznamů index sníží počet porovnání při hledání záznamu z 1 000 000 na pouhých 20 (jakoby tabulka měla jen 20 záznamů).
Samozřejmě, že vyhledávání je složitější pokud mluvíme o času na jedno porovnání, neboť se musí složitě rozhodovat, jaký další záznam zkusit.
Index má z toho důvodu smysl používat jen u tabulek, které mají netriviální počet řádků (řekněme alespoň stovky), ale naštěstí databáze se sama, zda je index vhodné použít.
Další nevýhodou indexu je zpomalení každého INSERTu a DELETu, neboť se musí nejen aktualizovat samotná tabulka, ale i stuktura indexu.
Většinou to nevadí, protože operace SELECT je mnohonásobně častější než INSERT a DELETE (příkladem je e-shop u kterého se produkty mění málokdy, ale tisíce uživatelů si je prohlédnou).
Nevyplatí se tedy mít indexů na tabulce příliš (více jak desítky).

Pak existují složené indexy, tedy index nad skupinou sloupců, ty slouží k urychlení vyhledávání pomocí více podmínek najednou.
U takového indexu záleží na pořadí sloupců, přečti si Větší databáze a indexy nad více sloupci.
Existují i jiné typy indexů:
- bitové, které mají za úkol filtrovat najednou podle mnoha parametrů, které nabývají málo hodnot (muž/žena, svobodný/ženatý/vdovec)
- fulltextové, které umožňují hledat slova v delších textech, často umí i ohýbání slov či kontrolu, zda se slova vyskytují dostatečně blízko u sebe.

V praxi prostě řekneš databázi, že máš zájem o index nad tímto sloupcem / těmito sloupci a ona se o všechno postará.
Index použije, když si bude myslet, že to dotaz urychlí (existuje i možnost vynutit si použití některého indexu, pokud si myslíš, že jsi chytřejší než databáze).
Pro jednoduché dotazy bez JOINů či vnořených SELECTů nemá databáze prakticky šanci chovat.

Klíč je speciálním typem indexu, u kterého jsou navíc kontrolovány podmínky.
Primární klíč vyžaduje, aby hodnota v sloupci (či sloupcích u složeného primárního klíče) byla vyplněna (NOT NULL) a zároveň musí být unikátní (nesmí se opakovat).
Primární klíč může v tabulce existovat jen jeden; reprezentuje informaci, která záznam jednoznačně identifikuje.
Unikátní klíč je oslabením primárního klíče, umožnuje zadat nevyplněnou hodnotu.

Pak je ještě cizí klíč, který není indexem, přesto se hodí nad ním vytvořit index manuálně.
Účelem cizího klíče je kontrola, zda existuje záznam v jiné tabulce.
Pokud máš tabulku příspevky a uživatelé a každý příspěvek má autora, chceš zajistit, aby vždy existoval, aby nebylo možné vytvořit příspěvek neexistujícího autora nebo naopak smazat uživatele, který má nějaké přispěvky bez toho, aby byly napřed odstraněny.

Toť teorie indexů a klíčů z rychlíku ;)
BunnyBugs
Profil *
Super, děkuji za rychlíkové vysvětlení, teď už jsem to pobral :)
Jak už jsem řekl výše, jsem v databázích teprve začátečník a zřejmě se nebudu pouštět do nějakých složitých databázových aplikací (nejsem programátor a dělám to jen pro svou potřebu), takže pro moje použití je zřejmě použití indexů a klíčů zbytečné. Samozřejmě primární ID nastavené mám.
Nebo použití indexů a klíčů doporučujete? Velikost mé databáze je zhruba 30 událostí za rok a ke každé události se nabaluje zhruba 30-40 záznamů, tj. celkem 1.200 řádků tabulky ročně.
juriad
Profil
BunnyBugs:
Ano, netřeba se jimi trápit, dokud nenarazíš na výkonostní problém. V takovém případě se klidně ozvi tady na diskusi s popsaným databázovým schématem a dotazem, který se pomalý (a výpisem explain z databáze).

Vaše odpověď

Mohlo by se hodit


Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm:

0