Autor Zpráva
Kcko
Profil
Ahoj,
chci se jen poradit o lepší DB návrhu.

Ve svých projektech jsem měl vždy jeden konkretní sport, takže tabulka zápasů (výsledků) měla jasně definované sloupce pro daný sport.

Fotbal se hraje na poločasy, takže byly třeba tyto sloupce.

results
===
id | home_team_id | away_team_id | home_team_score_half | away_team_score_half | home_team_score_full | away_team_score_full

Hokej na třetiny, takže by těch výsledkových sloupců bylo víc (1 třetina, 2 třetina, 3 třetina, celkový výsledek), Basket na čtvrtiny atd ...


Chci ted vyrobit web s více sporty (kolektivními, zatím třeba jen hokej / fotbal / basket) a tenhle db model už nedává smysl.

Budu nad tím řádně přemýšlet, ale napadá mě zatím v zjednoduššeném pohledu toto.

results
===

id | home_team_id | away_team_id | result_id


result 
===
id | team_id| result_type_id | score

result_type
===
id | name | rank 
1 | 1. poločas | 1
2 | 2. poločas | 2
3 | 1. třetina  | 3
.
.
.
500 | celkový výsledek | 500

Něco v tomhle smyslu. Bohužel se mi hodně zhorší jednoduché sumarizační přehledy typu
- 10 nejvíc střílejích týmů v daném sportu
- 10 týmu co dostali nejvíc branek
- Počet branek za jednotlivá herní kola atd ...


Napadá někoho jednoduší / lepší model?

Díky :)
juriad
Profil
Pokud chceš podporovat i sporty jako je třeba biatlon, tak ani home a away nebude stačit. V některých sportech není počet částí pevně daný (tenis může skončit dříve, golf se může protáhnout). Někdy je cílem maximalizovat skóre (desetiboj), jindy minimalizovat (běh). Někdy je pořadí dáno sekvencí výsledků parametrů (šachy). Zmiňuješ hokej, který může mít prodloužení a nájezdy.

Pokud přijmeš nějaká omezení, nevidím na tom schématu nic špatného.

Nabídnu univerzální řešení - události. Kdykoli někdo skóruje gól nebo doběhne, vytvoříš událost:

event
=====
match | participant | time | type

Pak je vyhodnocení počtu gólů za třetiny a celkově otázkou aplikační logiky, která bude odlišná pro fotbal a hokej. Otázkou je, jestli máš informace s takovou granularitou.
Kcko
Profil
juriad:
Ahoj, budou to kolektivní sporty pro víc lidí a spíš ty známější (zatím fotbal / hokej, časem asi basketbal nebo pingpong), biatlon a podobné šílenosti se konat nebudou.

To co ty ukazuješ v závěru je hezké, ale to je spíš statistika pro daného hráče ne pro tým jako celek.

A takhle už ty statistiky jedn. hráčů vlastně už na starším projektu řeším.

Zajímal mě onen návrh na skóre v zápasů mezi týmy. (Vždy to budou 2 týmy proti sobě, takže složitější vazba nebude, takže vždy home x away).
Šlo mi to jak rozložit ten výsledek, který se pro každý sport určí a počítá jinak (poločas x třetiny x čtvrtiny; může tam být prodloužení atd.)

Budu nad tím muset ještě přemýšlet, ale pokud to vidíš odbdobně jako já; jsem na dobré cestě :-)

PS. Já jsem taky omezen trošku CMSkem, který s takovým to rozdrobením "sloupce" do více tabulek a řádků nepočítá, bude trošku oříšek.

Díky.
ttttt
Profil *
To, co navrhuje juriad se mi líbí. Pokud máš k dispozici údaje, kdy do skóroval, dají se z nich dělat zajímavé statistiky (v posledních 5 minutách padá 20 % gólů). K času uložit i číslo poločasu / třetiny, ve které se to stalo. U zápasu pak uložit, kolik měl "poločasů".

Případně by se dala udělat i struktura matches(id), parts(match_id, order, duration), points(part_id, player_id, time). Je to hodně variabilní, ukládá to i informaci, kolik částí zápas měl, že se hrály tři prodloužení.

Moc se mi nelíbí ukládání home_* a away_*, ale vnímám to spíš jako osobní preferenci. Zdá se mi, že ve výsledku jsou složitější dotazy. Alternativa je uložit informaci to sloupce (enum 'home', 'away'). Uvažuju třeba dotazy "kolik gólů dal tým", "kolik gólů dal tým doma", "kolik gólů dal tým venku". Při první reprezentaci je potřeba měnit vybírané sloupce v dotazu, při druhé se mění je podmínka ve where. Zdá se mi, že musíš ve spoustě dotazů sčítat home+away, duplikovat části pro home / away. Myslím, že jsem to tak na jednom projektu tak začal a pak přešel k té druhé variantě, která tam je doteď, a jsem spokojený. Každopádně je jednoduché udělat jedno jako tabulku a druhé jako view, pokud těch záznamů není opravdu hodně, rychlé to bude obojí podobně.

Podobně bych chtěl mít rozlišené dotazy "kolik gólů dal tým", "kolik gólů dal tým v prvním poločase", "kolik gólů dal tým v druhém poločase" jen jednoduchou podmínkou ve where. Celkový výsledek bych uložil jen pokud by to bylo potřeba kvůli rychlosti nebo faktu, že informace, kdy góly padly chybí.

Kcko:
To co ty ukazuješ v závěru je hezké, ale to je spíš statistika pro daného hráče ne pro tým jako celek.
Dotazy pro hráče a pro tým by taky měly ideálně vypadat skoro stejně, lišit je jedním joinem nebo podmínkou ve where.
Kcko
Profil
ttttt:
To co navrhuje Juriad a to co se líbí tobě jsou ale jednotlivé akce zápasu. Já potřebuji, ale souhrnné za určitou část zápasu, tak abych z toho postupně složil celý zápas (resp měl jej evidovaný) a dalo se s tím pak rozumně pracovat.

Těžko se mi bude pracovat s X řádky, ze kterých složím jeden a ten poté budu ještě dál sčítat, abych třeba zjistil v tabulce pořadí kolik měl tým hráčů.

Vím (snad) o čem mluvím, provozoval jsem několik herních portálů (fotbal / hokej) i sportovních (skutečný sport) a vím jaké tam jsou požadavky a případné "problémy.

Každopádně díky za názor.


Skládat všechno z tabulky eventů by bylo šílené. Vím, že si můžu udělat pohledy atd ale v určitých případech nelze vymyslet pohledy, které jsou rychlé, protože se filtruje ze zeskládané množiny a ta už v tu chvíli může být pomalá.

Jako poslední věc je to, že používám CMSko, které taky pracuje s určitou strukturu a nepočítá s tím, ze rozumně zobrazí ve sloupcích data, která jsou vlastně v řádcích :-)

Chtěl jsem se o tom pobavit a zdá se, že mi bude stačit to co mi na začátku potvrdil Juriad.
juriad
Profil
Ten nápad s událostmi toto dovoluje - každou událost, kterou mám k dispozici - začátek zápasu, vstřelený gól, faul, prodloužení jde popsat. Nejspíš to nebude ve formátu, se kterým by bylo snadné pracovat - všechny operace vedou na nějaké agregace. Ale můžeme vedle této fronty událostí postavit jinou strukturu, která je vhodná pro dotazování - a tu automaticky plnit například pomocí triggerů nebo periodicky nějakým procesem. Tato technika se nazývá Event sourcing a CQRS a má mnoho výhod:
* primární data zůstávají na věky dostupná a nezměněná
* struktura sekundárních dat se může měnit - lze je přegenerovat z primárních dat
* lze poměrně jednoduše přidat další vypočítanou statistiku
* aplikaci lze škálovat - mít víc procesů, které zapisují do fronty, víc procesů, které odvozují statistiky z nových událostí ve frontě, víc procesů, které zodpovídají dotazy od uživatele
Ale pak už opouštíme klasické hostingy a přesouváme se do cloudu.

Nebál bych se případné změny schématu později - není to zas tolik práce. Důležitější je nepřijít o data. Primárně bych se snažil uložit všechna data, která jsou k dispozici, byť teď pro ně není využití.
Můžeš začít s tím, co máš. Statistiky můžeš řešit třeba pomocí materializovaných pohledů, pokud zjistíš, že selecty jsou pomalé - předpokládám, že statistiky se nemusí refreshovat příliš často. Případně si je budeš ukládat bokem a přepočítávat při každém zápisu - předpokládám, že zápasy nekončí každou sekundu. A možná časem doiteruješ k něčemu obecnějšímu.
Kcko
Profil
juriad:
Jasně vím, šlo mi o ten základ, ten jsi mi potvrdil. To mě trošku ujistilo, že nevymýšlím koninu, budu nad DB modelem ještě přemýšlet, když jsem to psal, tak jsem nad tím přemýšlel asi tak 20 minut. Sepíšu si co v budoucnu může vzniknout a doupravím to, zatím si budu připravovat UX prototyp ve figmě a až pak se vrhnu na DB, ráno moudřejší večera :-).

PS. Triggery můžou být dobrým pomocníkem, stejně jako pekelnou bestií když jich je hodně kříží se.

Díky.

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