Autor Zpráva
4ever
Profil
Chtěl bych zde zahájit diskusi o stránkování. Jaké znáte knihovny na stránkování, nebo jaký druh stránkování upřednostňujete?

Kdysi jsem používal dvě funkce, na stránkování a ty pracovali na principu, že se vypsaly čísla stránek (nikoliv čísla příspěvků) a to buď od začátku nebo od konce (reverzně). Teď bych to chtěl předělat do třídy ale zjistil jsem že je více způsobů jak stránkování udělat.

Dříve jsem používal jako hlavní argument číslo stránky. Tam je nevýhoda, že musíte nejdříve zjistit kolik je záznamů v tabulce. Když je to soubor, znamená to nejdříve načíst celý soubor a pak spočítat které záznamy chcete vypsat.

1. Jak to má databáze mysql? Když chci vrátit počet záznamů v tabulce, tak nemusím dávat dotaz na všechny záznamy, ne? Nebo to musí mysql server přepočítávat?

2. Co je lepší udělat
A) argument pro stránkování (v odkazu) podle čísel stránek nebo
B) podle id (argument v odkazu ukazuje id)?
Béčko znamená že budete mít asi takový kód:
<a href="http://localhost/ci/page/index/">&lsaquo; First</a>&nbsp;&nbsp;<a href="http://localhost/ci/page/index/1435">&lt;</a>&nbsp;<a href="http://localhost/ci/page/index/1370">275</a>&nbsp;<a href="http://localhost/ci/page/index/1">1</a>&nbsp;
<a href="http://localhost/ci/page/index/2">2</a>&nbsp;
<a href="http://localhost/ci/page/index/3">3</a>&nbsp;
<a href="http://localhost/ci/page/index/4">4</a>&nbsp;
<a href="http://localhost/ci/page/index/5">5</a>&nbsp;
<a href="http://localhost/ci/page/index/6">6</a>&nbsp;
<a href="http://localhost/ci/page/index/7">7</a>&nbsp;
<a href="http://localhost/ci/page/index/8">8
</a>&nbsp;<a href="http://localhost/ci/page/index/9">9</a>
&nbsp;<a href="http://localhost/ci/page/index/10">14</a>
&nbsp;<a href="http://localhost/ci/page/index/11">13</a>
&nbsp;<a href="http://localhost/ci/page/index/12">12</a>
&nbsp;<a href="http://localhost/ci/page/index/13">13</a>
&nbsp;<strong>289</strong><br />


Jako hlavní nevýhoda se zdá, že po uložení odkazu se po čase dostanete na jiný příspěvek než kde jste byly.

Béčko znamená že v odkazu budete mít něco jako

<a href="http://localhost/ci/page/index/">&lsaquo; First</a>&nbsp;&nbsp;<a href="http://localhost/ci/page/index/1435">&lt;</a>
&nbsp;<a href="http://localhost/ci/page/index/1370">275</a>&nbsp;
<a href="http://localhost/ci/page/index/103075">276</a>&nbsp;
<a href="http://localhost/ci/page/index/103080">277</a>&nbsp;
<a href="http://localhost/ci/page/index/103085">278</a>&nbsp;
<a href="http://localhost/ci/page/index/103090">279</a>&nbsp;
<a href="http://localhost/ci/page/index/103095">280</a>&nbsp;
<a href="http://localhost/ci/page/index/104000">281</a>&nbsp;
<a href="http://localhost/ci/page/index/104005">282</a>&nbsp;
<a href="http://localhost/ci/page/index/104010">283</a>&nbsp;
<a href="http://localhost/ci/page/index/104015">284</a>&nbsp;
<a href="http://localhost/ci/page/index/104020">285</a>&nbsp;
<a href="http://localhost/ci/page/index/104025">286</a>&nbsp;
<a href="http://localhost/ci/page/index/104030">287</a>&nbsp;
<a href="http://localhost/ci/page/index/104035">288</a>&nbsp;<strong>289</strong><br />


(První číslo je id druhé je stránka).


Pak je tu ještě jeden způsob výpisu a to takový
<div class="10red">&nbsp;[ Všech vzkazů je celkem: <b>304</b>
                  | Zobrazeny jsou vzkazy: <b>1&mdash;30</b> ]<br>
&nbsp;[ 1&mdash;30 | <a href="portal.php?sc=vzkaznik&amp;limit=30">31&mdash;60</a> | <a href="portal.php?sc=vzkaznik&amp;limit=60">61&mdash;90</a> | <a href="portal.php?sc=vzkaznik&amp;limit=90">91&mdash;120</a> | <a href="portal.php?sc=vzkaznik&amp;limit=120">121&mdash;150</a> | <a href="portal.php?sc=vzkaznik&amp;limit=150">151&mdash;180</a> | <a href="portal.php?sc=vzkaznik&amp;limit=180">181&mdash;210</a> | <a href="portal.php?sc=vzkaznik&amp;limit=210">211&mdash;240</a> | <a href="portal.php?sc=vzkaznik&amp;limit=240">241&mdash;270</a> | <a href="portal.php?sc=vzkaznik&amp;limit=270">271&mdash;300</a> | <a href="portal.php?sc=vzkaznik&amp;limit=300">301&mdash;330</a> ] <br></div>


A výstup vypadá takto:
[ 1—30 | 31—60 | 61—90 | 91—120 | 121—150 | 151—180 | 181—210 | 211—240 | 241—270 | 271—300 | 301—330 ]

Tohle zabírá více místa, ale zase je to velice přehledné.

Tak co z toho vybrat, co by jste ne/doporučili?
__construct
Profil
4ever:
…Tam je nevýhoda, že musíte nejdříve zjistit kolik je záznamů v tabulce…
To je obecný „problém“ pri stránkovaní

1. Jak to má databáze mysql? Když chci vrátit počet záznamů v tabulce, tak nemusím dávat dotaz na všechny záznamy, ne? Nebo to musí mysql server přepočítávat?
Buď sa použije dotaz na spočítanie riadkov v tabuľke:
SELECT 
COUNT(indexovanyStlpec) pocet -- namiesto indexovaného stĺpca môžeš použiť aj *
FROM tabulka
-- môžeme použiť aj podmienku
WHERE podmienka;
alebo pokiaľ nepotrebuješ podmienky si môžeš informácie vytiahnuť zo systémovej tabuľky

Teď bych to chtěl předělat do třídy ale zjistil jsem že je více způsobů jak stránkování udělat.
A na čo? Keďže používaš CodeIgniter tak môžeš použiť ich knižnicu.
4ever
Profil
__construct:
No super. Díky za ten odkaz na Diskusi o InnoDB. O tom information_schema slyším poprvé. Rozumím tomu správně manuálu , že jedním jednoduchým příkazem získám přístup k množství různým informací, které jsou zapsány v databázi? Nemusím tu tabulku vytvářet, ta už tam je jo?

O knihovně pagination v CI vím, ale právě že bych si raději udělal vlastní. Jak jsem psal je tu více možností, tak bych chtěl zvážit které za to stojí a třeba udělat knihovnu hned se třemi řešeními. Moje funkce zabraly jen 38 řádků, no když to předělám na OOP snad to nebude moc velké. Chci zkusit jiný přístup a aby knihovna zabírala méně než ta jejich.
Alphard
Profil
[#2]
Měřil jste někdo, jestli je vytahování ze systémové tabulky (výrazně) rychlejší než count? Já vidím přínos tohoto řešení spíš pesimisticky, protože čas count je běžně nula nula nic.

4ever:
Lze využít SQL_CALC_FOUND_ROWS, viz http://php.vrana.cz/ziskani-poctu-radek.php, osobně ale často zůstanu u dvou dotazů s klasickým count().

Jak __construct odkazoval na CodeIgner, já zase používám http://addons.nette.org/cs/visualpaginator, který využívá výpočtového jádra http://api.nette.org/2.0/Nette.Utils.Paginator.html. Každý fw má dneska svoje řešení.
To je tak vše k technické stránce.

Chtěl bych zde zahájit diskusi o stránkování.
http://zdrojak.root.cz/clanky/strankujeme-smysluplne/
http://zdrojak.root.cz/clanky/strankovani-vam-muze-snizit-procento-okamzitych-odchodu/
http://www.sovavsiti.cz/weblog/156/stankovani-v-case
4ever
Profil
Alphard:
Ten count záleží na tom jaké uložiště používáš nebo jakou máš konfiguraci InnoDB. Dočetl jsem se o tom v komentářích zde:
Odkaz

Ale co se týče těch výkonů funkcí, tak to asi taky závisí na typu uložiště a na dalších faktorech.

Dík za odkazy, chvíli to potrvá než to projdu
__construct
Profil
Alphard:
Měřil jste někdo, jestli je vytahování ze systémové tabulky (výrazně) rychlejší než count? Já vidím přínos tohoto řešení spíš pesimist1cky, protože čas count je běžně nula nula nic.
Ja som teraz testoval počítanie na InnoDB tabuľku ktorá má cca. 2,8 mil. riadkov a v priemere to počíta 2 sekundy. Oproti tomu vytiahnutie tej informácie zo systémovej tauľky trvá v priemere 0,15 sekundy. U MyISAM tabuliek je COUNT samozrejme okamžitý.

Inak na CodeIgniter som odkazoval, lebo 4ever ho používa — netvrdím, že tá knižnica je nejaká prelomová.
Prečo je vo filtri sprostých slov st1cky? som zistil
4ever
Profil
Alphard:
K tomu VIsual Paginatoru. Vypadá to docela slibně. Nezaznamenal si nějaký problém s podezřelým měněním šířky toho výpisu linků? U CI totiž mi vadilo právě to, že když jsem kliknul na nějaký odkaz, například str. 4. tak nejdříve je úzký výpis. Pak klikneš na 8 a ono se to roztáhne a myslím, že tam i přibudou čísla. Takže opticky se to zvětší. Když klikneš třeba na 100, 150 tak se to roztáhne ještě více. Nevím zda to funguje takhle všude, ale nevypadá to moc dobře, když se to příliš roztahuje. Takže asi vyzkouším to co používáš ty anebo naprogramuju vlastní.

Edit:
Ten tvůj mi nepojede, jede to na jiném Frameworku :-)
Alphard
Profil
__construct:
Promiň, měl jsem přečíst celé odkazované vlákno, já myslím (doufám :-)) v žádné InnoDB nemám miliony záznamů.

4ever:
Je to doplněk pro Nette, jestli jedete na CodeIgneru, tak to asi moc nepomůže.
Toto chování (že z první stránky vede méně odkazů než z prostřední je typické pro tento styl stránkování. Pokud jde o 100 (a více ciferná čísla), je to otázka css stylu, jak velké písmo, padding, pevná šířka prvku...
Celé je to ale snadno upravitelné.
Mastodont
Profil
__construct:
Ve většině (?) případů ale nepotřebuješ počet záznamů v celé tabulce, ale v podmnožině vrácené nějakým SQL. A to v systémových tabulkách nanajdeš.
4ever
Profil
Alphard:
Aha. Tak to já jsem udělal spíš chybu v tom, že jsem dal moc velký počet linků na 14. Takže se ten rozdíl v šířce znásobil. No když dám počet linků na 6 tak je to znatelně lepší. Nicméně mě u CI pagination překvapuje právě to že místo 6-ti linků to ukazuje:
1 2 3 4 5 6 7
1 2 3 4 5 6 7 8 9 10 11 12 13
279 280 281 282 283 284 285 286 287 288 289

10 až 12 linků. Proto se mi ta jejich knihovna nějak nezná. Funguje tak nějak zvláštně.

Edit:
Nevíš kde najdu tu knihovnu Nette paginator?, kdy Stáhl jsem si to do počítače celou aplikaci
Alphard
Profil
Jejich knihovnu neznám, ale nastavení počtu odkazů někdy není tak jednoduché, já mám třeba
Pro aktuální stranu 2:
« Přechozí 1 2 3 4 5 … 7 … 9 … 12 Další »
Lze dopředu i dozadu. Existují-li dané stránky, vypíše se:
3 následující dopředu/dozadu, číselný odkaz na první/poslední, několik mezikroků mezi aktuální a poslední (velmi užitečené u velkch rozsahů, kde se lze relativně na pár kliknutí dostat na jakokoukoliv stránku. Tady s max 12 kanón na vrabce, ale mám to tak udělané.

Je tam located at http://api.nette.org/2.0/source-Utils.Paginator.php.html#18
4ever
Profil
Alphard:
No pecka. Už jsem viděl tu jejich knihovnu a maj to úplně krásně přehledné, ne jak v CI. Tak se podívej:
http://nette.org/download
soubor Nette\Utils\Paginator.php
je dobrý zdroj inspirace.
Pak když dáš hledat paginator ve složce s testy tak ti to najde pokusné soubory s konfigurací a aplikací...
__construct
Profil
4ever:
Proto se mi ta jejich knihovna nějak nezná. Funguje tak nějak zvláštně.
Tá knižnica funguje úplne normálne — bez uražky, ale chyba je niekde medzi klávesnicou na stoličkou.

Do controlleru dáš:
$this->load->library('pagination');

$config['base_url'] = 'http://…/';
$config['total_rows'] = $this->model->pocetZaznamov(); //celkový počet záznamov
$config['per_page'] = 20; //počet záznamov na stránku
$config['uri_segment'] = 3; //odkiaľ sa bude brať offset
$config['num_links'] = 2; //koľko čiselných odkazov bude pred a za aktuálne zobrazenou stránkou
// …kopec iných možných nastavení

$this->pagination->initialize($config);

$data['zaznamy'] = $this->model->nacitajZaznamy($config['per_page'],$this->uri->segment(3)); //prvý argument je LIMIT, druhý OFFSET
$data['strankovanie'] = $this->pagination->create_links();
$this->load->view('sablona',$data);

A do viewu si umiestniš <?php echo $strankovanie; ?> kde potrebuješ.
4ever
Profil
__construct:
Tos ani nemusel posílat mám to prakticky stejně jak to tady ukazuješ. Já jsem přece neříkal, že mi to nefunguje. Vždyď jsem i posílal co mi to vypisuje za výstup. Chceš říct, že tobě se to chová jinak než mě?
__construct
Profil
4ever:
Chceš říct, že tobě se to chová jinak než mě?
Nie nechová, ale to čo potrebuješ sa dá nastaviť. Chcel som len ukázať na margo toho „…funguje tak nějak zvláštně…“, že funguje iba tak, ako si to nastavíš. Pokiaľ Ti na nej niečo nevyhovuje stačí vytvoriť v application/libraries/ triedu MY_Pagination a to čo Ti nevyhovuje upraviť. Na aplikáciách kde som používal CI som Pagination upravoval zriedkakedy, a aj to šlo o marginálne úpravy.
4ever
Profil
__construct:
Mě se celkově ta knihovna zdá nepřehledná a moc komlikovaná, takže kdybych ji chtěl rozšiřovat tak bych ji nejspíš nerozuměl. Proto raději zkusím vytvořit svou. Však mám na to algoritmus o 38 řádcích a ten funguje bezvadně. Takže si ho jen upravím a rozšířím. No pohraju si s tím a uvidíme co z toho vyleze.
4ever
Profil
Alphard:
Tenhle odkaz cos poslal je hodně dobrý:
root.cz
V části "Definice problému a idea" to je trefa do černého:
do www adresy neuvádět stranu, ale číslo článku, “od kterého dál” se má obsah načíst. aby nedošlo ke snížení návštěvnosti.
Takže mi to pomohlo se rozhodnout.
joe
Profil
Pokud bych měl dělat stránkování tak, aby na adresách zůstal původní obsah, udělal bych to takhle:

seznam ID: 1 2 3 4 5 6 7 8 9 10
počet na stránku: 3

1 2 3 ... str. 1 ... zoobrazit uživateli jako str. 4
4 5 6 ... str. 2 ... zoobrazit uživateli jako str. 3
7 8 9 ... str. 3 ... zoobrazit uživateli jako str. 2
8 9 10 . str. 4 ... zoobrazit uživateli jako str. 1

Na první straně bych vypsal tolik, kolik je potřeba, takže 3 (proto jsou na straně 2 a 1 duplikace), ale zdá se mi to pořád lepší mít duplikace jen na těchto dvou stranách, než to mít poházené na víc adresách - když to uděláš tak, že to budeš zobrazovat od určitého ID.

Není to lepší? :-) Možná v tom nevidím teď nějaký problém...
4ever
Profil
joe:
S těma duplikacema jsem se u starého systému nesetkal, tak nevím jak ty duplikace vznikají?

Ale já bych právě zavedl hned tři až čtyři možnosti zobrazení nebo více.

Protože můžeš zobrazit buď čísla stránek (), nebo pořadová čísla příspěvků (první,druhý,dvoustý, pětistý, atd.). To ale předpokládá že stránkuješ od nejstarších po novější, což mi přijde nepraktické. Každý chce, aby se mu článek nebo diskuse otevřela hned na nejnovějších příspěvcích. Takže se otevírají další dvě možnosti, buď číslování 1až n (horní limit), ale otvírat budeš id od n až po 1 (číselné hodnoty od největšího po nejmenší). To samé by mohlo platit o pořadových číslech, případně rozsazích stran př. 250-231, 230-201, 200-171, 170-141, 140-101.

Ale zase na druhou stranu ono by se nic nestalo když by to bylo od nejnovějších po nejstarší, ale číslování by bylo od nejmenšího po největší...
4ever
Profil
........ smazáno.......
4ever
Profil
..........

Vaše odpověď

Mohlo by se hodit

Odkud se sem odkazuje


Prosím používejte diakritiku a interpunkci.

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

0