IT rekvalifikace s garancí práce. Seniorní programátoři vydělávají až 160 000 Kč/měsíc a rekvalifikace je prvním krokem. Zjisti, jak na to!
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.
Avatar
David Hartinger
Vlastník
Avatar
David Hartinger:10.11.2012 13:57

Zdravím, již chvilku si lámeme hlavu nad tím, jak zobrazovat počty článků v sekcích tak, aby se zohlednilo zanoření několika sekcí do sebe. Příklad:

V sekci "HTML" je podsekce "HTML manuál" a ten bych moc rád tématicky rozdělil do podsekcí jako např. "Tabulky" nebo "Odstavce". Když bude v tabulkách 5 článků a v odstavcích 10, mělo by se u sekci HTML manuál zobrazit, že obsahuje 15 článků, teď by se tam zobrazilo, že obsahuje 2 (tedy ty 2 sekce tabulky a odstavce).

Jsem smířen s tím, že řešení nebude hezké :) Díky za jakýkoli nápad.

Odpovědět
10.11.2012 13:57
New kid back on the block with a R.I.P
Avatar
Kit
Tvůrce
Avatar
Odpovídá na David Hartinger
Kit:10.11.2012 14:07

Rekurze se v SQL dělá blbě, resp. nedá se udělat efektivně. Asi to bude chtít mírnou denormalizaci a přidat do podsekcí sloupec s počtem článků. Tento sloupec pak aktualizovat např. triggerem při manipulaci s články.

Nahoru Odpovědět
10.11.2012 14:07
Vlastnosti objektů by neměly být veřejné. A to ani prostřednictvím getterů/setterů.
Avatar
David Hartinger
Vlastník
Avatar
Odpovídá na Kit
David Hartinger:10.11.2012 14:25

Díky za reakci. Toto řešení nás napadlo, ale když došlo na implementaci, nějak jsme se na tom zasekli, mám hrozně nerekurzivní myšlení :) Hlavně nevím, jak to obnovovat, předpokládám, že celé najednou by to trvalo dlouho, čili bychom potřebovali metodu, která nám refreshne počet článků u 1 sekce a všech jejich nadsekcí. Znamená to, že máme udělat refresh té jedné sekce a potom si hodit querku, jestli ta sekce není náhodou do nějaké vnořená a pokud ano, celou akci opakovat? Naštěstí máme vazbu sekce-článek jen 1:N.

Nahoru Odpovědět
10.11.2012 14:25
New kid back on the block with a R.I.P
Avatar
David Hartinger
Vlastník
Avatar
Odpovídá na Kit
David Hartinger:10.11.2012 14:35

Hlavně mi tam chybí hodně informací, možná bych to potřeboval nejdříve celé spočítat nějakým skriptem a dalším jen refreshovat jednu sekci, co se změnila.

Nahoru Odpovědět
10.11.2012 14:35
New kid back on the block with a R.I.P
Avatar
Kit
Tvůrce
Avatar
Odpovídá na David Hartinger
Kit:10.11.2012 14:52

Myslel jsem to tak, že by se např. při přidání článku do sekce inkrementoval čítač v sekci, následně by se inkrementoval i čítač v nadřízených sekcích až ke kořeni.

Bohužel na takové opičky nejsou SQL databáze stavěny. Jedině snad přes ten trigger.

Ještě mě napadla jedna varianta: Natáhnout seznam sekcí (stačí jen id a parent_id), průchodem od listu ke kořeni vybrat id sekcí (např. 5, 18, 200) a pak už jen

UPDATE sekce SET pocet=pocet+1 WHERE id IN (5, 18, 200);
Nahoru Odpovědět
10.11.2012 14:52
Vlastnosti objektů by neměly být veřejné. A to ani prostřednictvím getterů/setterů.
Avatar
Kit
Tvůrce
Avatar
Odpovídá na David Hartinger
Kit:10.11.2012 17:00

Zkusil jsem to udělat tím triggerem, ale bohužel nezvládne rekurzi.

Nahoru Odpovědět
10.11.2012 17:00
Vlastnosti objektů by neměly být veřejné. A to ani prostřednictvím getterů/setterů.
Avatar
Kit
Tvůrce
Avatar
Odpovídá na David Hartinger
Kit:10.11.2012 17:27

Ještě doplním, že v SQLite to s tím triggerem funguje parádně.

Nahoru Odpovědět
10.11.2012 17:27
Vlastnosti objektů by neměly být veřejné. A to ani prostřednictvím getterů/setterů.
Avatar
David Hartinger
Vlastník
Avatar
Odpovídá na Kit
David Hartinger:10.11.2012 17:38

Ony právěže ty sekce nemají parrent_id. Musím to nějak denormalizovat asi. Současný stav je následující:

tabulka sekce obsahuje sekce spolu s informací v jakém jazyce jsou zdrojové kódy v sekci. Dále je tu odkaz na článek, který sekci reprezentuje.

článek má potom informaci do které sekce patří (což může jako článek obyčejný i jako článek reprezentující sekci). Čili já z tabulky sekcí nezjistím, kdo je rodič, musím tam najoinovat článek. A to jsem chtěl ještě vazbu rozšířit na M:N, to by to už asi úplně pohřbilo :)

Nahoru Odpovědět
10.11.2012 17:38
New kid back on the block with a R.I.P
Avatar
Kit
Tvůrce
Avatar
Odpovídá na David Hartinger
Kit:10.11.2012 17:46

Viděl bych to na zrušení tabulky sekce. Informace o sekcích by pak byly jako další záznamy mezi články. Článek by měl své id a parent by označoval sekci. Sekce by měla své id a parent by odkazoval na nadřízenou sekci. Nejvyšší sekce by měly parent=null.

Nahoru Odpovědět
10.11.2012 17:46
Vlastnosti objektů by neměly být veřejné. A to ani prostřednictvím getterů/setterů.
Avatar
Kit
Tvůrce
Avatar
Odpovídá na David Hartinger
Kit:10.11.2012 18:09

Jen tak pro zajímavost malá ukázka, jak to funguje v SQLite.

PRAGMA recursive_triggers = on;
CREATE TABLE sekce(id integer primary key autoincrement, parent int, nazev text, pocet int);
INSERT INTO "sekce" VALUES(1,NULL,'PHP',0);
INSERT INTO "sekce" VALUES(2,NULL,'C#',0);
INSERT INTO "sekce" VALUES(3,8,'Java',0);
INSERT INTO "sekce" VALUES(4,1,'Databaze v PHP',0);
INSERT INTO "sekce" VALUES(5,1,'Vyjimky v PHP',0);
INSERT INTO "sekce" VALUES(6,3,'Java na desktopu',0);
INSERT INTO "sekce" VALUES(7,3,'Java na serveru',0);
INSERT INTO "sekce" VALUES(8,NULL,'sekce pro Javu',0);
CREATE TRIGGER tr_sekce UPDATE OF pocet ON sekce
   BEGIN
   UPDATE sekce SET pocet=pocet-old.pocet+new.pocet WHERE sekce.id=old.parent;
   END;

Při aktualizaci pocet např. u id=7 se aktualizuje i id=3 a 8.

Nahoru Odpovědět
10.11.2012 18:09
Vlastnosti objektů by neměly být veřejné. A to ani prostřednictvím getterů/setterů.
Avatar
David Hartinger
Vlastník
Avatar
Odpovídá na Kit
David Hartinger:10.11.2012 18:15

A nebude to moc denormalizované? Sekce bude mít navíc počet článků uvnitř, titulek (je často jiný, než článku), jazyk a ještě jsem plánoval další vlastnost, která by určovala od jakého čísla číslovat články. Tak by se daly udělat navazující seriály přes několik sekcí a šlo by mezi díly jednoduše řadit další bez nutnosti manuálního přečíslování. To jsou 4 prázdné sloupce u většiny článků, už teď jich má 25 :)

Na tu vazbu M:N se tedy asi vykašlu, ušetří to hodně problémů a nechceme jen psát redakční systém :)

Nahoru Odpovědět
10.11.2012 18:15
New kid back on the block with a R.I.P
Avatar
Kit
Tvůrce
Avatar
Kit:10.11.2012 18:24

Počet článků bude u článku roven 1, sloupec s titulkem bude sdílený (sekce je v jiném záznamu) jazyk by měl být u každého článku, číslování článků je zdrojem problémů. Tedy bez prázdného sloupce.

Z článku se snadno může stát sekce. To nezní špatně.

Navazující seriály se dají udělat přes URL v článku či sekci.

Editováno 10.11.2012 18:28
Nahoru Odpovědět
10.11.2012 18:24
Vlastnosti objektů by neměly být veřejné. A to ani prostřednictvím getterů/setterů.
Avatar
Kit
Tvůrce
Avatar
Odpovídá na David Hartinger
Kit:10.11.2012 18:34

Sekce jsou uzly a články jsou listy stromu. V principu není velký rozdíl mezi uzlem a listem a sjednocení přístupu zpravidla vede ke zjednodušení aplikace.

Nahoru Odpovědět
10.11.2012 18:34
Vlastnosti objektů by neměly být veřejné. A to ani prostřednictvím getterů/setterů.
Avatar
David Hartinger
Vlastník
Avatar
Odpovídá na Kit
David Hartinger:10.11.2012 18:53

A jakým způsobem udělám naplnění toho počtu článků v sekci poprvé, když bude ten sloupec ještě prázdný? Nějak mě nenapadá za který konec to vzít :)

Číslování článků mi tu chybí i když je to další komplikace, ty seriály by lépe vynikly. Máme sloupec, kde je pořadové číslo článku v sekci (tak jim určujeme pořadí výpisu, máme javascriptový widget, kde je myší seřadíme a on je tak očísluje), asi by se to dalo využít pro tento účel a s omezením, že by samostatné články nebyly mezi lekcemi, by to mohlo docela fungovat.

Nahoru Odpovědět
10.11.2012 18:53
New kid back on the block with a R.I.P
Avatar
Kit
Tvůrce
Avatar
Odpovídá na David Hartinger
Kit:10.11.2012 19:16

To nebude zas tak složité. Záleží na tom, jestli do tabulky prvně uložíš sekce nebo články. Případně tam dáš všechno, necháš to propočítat a aktivuješ trigger.

Číslování článků můžeš udělat ve výstupní šabloně, v DB to být nemusí. Alespoň nebudeš muset řešit přečíslování.

Číslování sekcí by také mohlo mít svůj význam.

Nahoru Odpovědět
10.11.2012 19:16
Vlastnosti objektů by neměly být veřejné. A to ani prostřednictvím getterů/setterů.
Avatar
David Hartinger
Vlastník
Avatar
Odpovídá na Kit
David Hartinger:10.11.2012 19:20

No já nevím jak to nechat propočítat :) Potřeboval bych začít od těch nejnižších sekcí, ale jak je poznám?

V šabloně by to šlo v seznamu článků, ale když si ho otevřu, ten článek už neví, jak byl předtím vypsán. Sekcím jsem chtěl dát číslovací offset, abych mohl dělat seriály přes sekce.

Nahoru Odpovědět
10.11.2012 19:20
New kid back on the block with a R.I.P
Avatar
Kit
Tvůrce
Avatar
Odpovídá na David Hartinger
Kit:10.11.2012 19:31

Každý článek bude mít rodiče - sekci. Projedeš si selectem všechny články GROUP BY parent. Tím získáš počty v nejnižších sekcích. Aktualizuješ. Tak to projdeš až ke kořeni. Není to sice tak pohodlné jako rekurze, ale fungovat to bude.

Na konci článku je dobré vypsat seznam článků v sekci. Přitom se dá zjistit pořadí aktuálního článku (a ten jeden nedělat jako odkaz).

Nahoru Odpovědět
10.11.2012 19:31
Vlastnosti objektů by neměly být veřejné. A to ani prostřednictvím getterů/setterů.
Avatar
David Hartinger
Vlastník
Avatar
Odpovídá na Kit
David Hartinger:10.11.2012 19:53

Jsem z toho jelen :) GROUP BY jsem nikdy moc nepochopil a nevím, jak udělat, aby to do toho počtu nedávalo samotné sekce. No je to každopádně hrůza, asi zatím spíchnu nějaký work-around. Vnoření tolika sekcí do sebe tak, aby to bylo vidět, plánuji jen na 2 místech, tak to asi zatím zadám manuálně a bude :D

Na konec článku chci určitě dát nějaký widget, vídal jsem "podobné články", kompletní seznam sekce jsem ještě neviděl. Možná by bylo dobré 3 odkazy: předchozí, další a sekce.

Nahoru Odpovědět
10.11.2012 19:53
New kid back on the block with a R.I.P
Avatar
Kit
Tvůrce
Avatar
Odpovídá na David Hartinger
Kit:10.11.2012 20:07
SELECT parent, count(*) AS pocet FROM clanek WHERE NOT je_sekce GROUP BY parent;

Tohle si dáš do pomocné tabulky, podle které aktualizuješ. Pak si podle ní vyhledáš všechny rodiče aktualizovaných záznamů, zase aktualizuješ a tak dál, dokud nebude prázdná. V tom selectu už nebude count(*), ale sum(pocet).

Kompletní seznam článků sekce najdeš třeba na linuxsoft.cz.

Nahoru Odpovědět
10.11.2012 20:07
Vlastnosti objektů by neměly být veřejné. A to ani prostřednictvím getterů/setterů.
Avatar
David Hartinger
Vlastník
Avatar
Odpovídá na Kit
David Hartinger:10.11.2012 21:25

Díky, zatím to nějak nahackuji a potom se k tomu vrátím :)

Nahoru Odpovědět
10.11.2012 21:25
New kid back on the block with a R.I.P
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 20 zpráv z 20.