Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Wydarzenia meczu - jak w bazie MySQL najlepiej przechowywać?
Forum PHP.pl > Forum > Bazy danych > MySQL
Apocalyptiq
Piszę grę via www - siatkarski menedżer. Posiada się tam swoją drużynę, można z nią trenować itp. Aktualnie jestem przy systemie meczu - ma on wyglądać tak, że my nie ingerujemy w mecz - po prostu jest ustalony np. o 19:00 i o tej się zaczyna. Jak wejdziemy na stronę meczu, o 19:00 pojawi nam się komunikat że mecz się rozpoczął i co kilka sekund w raporcie tekstowym będzie pojawiała się kolejna akcja (co zdobycie punkta), np. ten zaserwował, ten odebrał, ten wystawił, ten przebił - punkt. Chcę to zorganizować tak: o tej np. 19:00 odpalam CRONem mecz - od razu generuje mi się cały mecz - każde wydarzenie zapisywane jest w bazie. Tylko teraz właśnie nie wiem w jakiej formie zapisywać te wydarzenia. Bo co, dać wyprzecinkowane w kolumnie "wydarzenia" po kolei wszystkie wydarzenia, a później rozbić to przecinkami? Wtedy np: "1s2,2o3,2w2,2p4" oznacczałoby: zawodnik z pierwszej drużyny z numerem (ID) 2 serwuje, gracz z drugiej drużyny z nr 3 odbiera, gracz z tej samej drużyny z nr 2 wystawia, gracz z tej samej drużyny z nr 4 przebija. Ale nie wiem czy to jest dobre rozwiązanie - trzebaby jeszcze jakiś oddzielnik dać pomiędzy poszczególnymi punktami itp. A chciałem też przy każdym zdobyciu punktu podawać czas, kiedy zdobyto punkt (czas zależny od długości akcji, oczywiście jakoś na oko obliczany). A chyba głupotą byłoby robienie osobnej tabeli dla każdego meczu, i każdy rekord byłby jedną akcją - z kolumnami czas - czas wystąpienia i wydarzenia - po kolei co się działo w danej akcji.
Jakie rozwiązanie do zapisywania tych logów z meczu będzie najlepsze? No i gdy ktoś wejdzie na stronę meczu, to następne akcje będą pobierane AJAXem co kilka sekund.

Może żeby to lepiej zobrazować, z tymi tabelami (choć wydaje mi się że to bezsensowne - dla każdego meczu osobna tabela, ale z drugiej strony można zrobić tabelę z akcjami ze wszystkich meczów, ale to pewnie nieźle zawaliłoby bazę):
Cytat
id czas (zdobycia pkta) wydarzenia punkt (która drużyna zdobyła)
1 20 1s1,2o3,2w2,2a1 2 (w 20 sekundzie druga drużyna zdobyła punkt po ataku zawodnika nr 1)
2 45 2s1,1o2,1p3,1a4,2b3 2 (w 45 sekundzie druga drużyna zdobyła punkt po udanym bloku zawodnika nr 3)

Jest sens tworzyć taką strukturę poszczególnych akcji meczu? Czy jest może jakiś inny lepszy sposób na to?
nexis
Cytat(Apocalyptiq @ 16.10.2008, 16:23:10 ) *
dla każdego meczu osobna tabela

Najgorsze i nie dopuszczalne rozwiązanie! Struktura tabel, czyli ilość kolumn, powiązań i liczność samym tabel powinna być niezmienna bez względu na ilość przetrzymywanych danych. Zapamiętaj to przy kolejnych przemyśleniach.
mike
Cytat(Apocalyptiq @ 16.10.2008, 16:23:10 ) *
Jest sens tworzyć taką strukturę poszczególnych akcji meczu?
Powiem szczerze. Takie podejście jest kompletnie pozbawione sensu.
Cytat(Apocalyptiq @ 16.10.2008, 16:23:10 ) *
Czy jest może jakiś inny lepszy sposób na to?
Oczywiście. Tabela events gdzie zapisujesz zdarzenia dot. każdego meczu. Na przykład (w skrócie)
Kod
id | match_id | event_description
Apocalyptiq
Ale czy to rozwiązanie nie zawali bazy? Dla każdego meczu ok. 150 wydarzeń, powiedzmy na początek 10 meczów w tygodniu - co daje nam 1500 rekordów na tydzień. Ale gdybym co jakiś czas czyścił bazę ze starszych meczów (bo początkowo chciałem, aby wydarzenia meczów zapisywały się na stałe, żeby można np. kilka dni po meczu przejrzeć akcja po akcji), to twoje rozwiązanie byłoby naprawdę spoko smile.gif Aha, i gdybym chciał pobierać wydarzenia według czasu wystąpienia (do tabeli events wrzuciłbym jeszcze czas wystąpienia - w sekundach od rozpoczęcia meczu), to należałoby dodać jakiś index dla czasu, żeby to szybciej działało? Czyli po prostu dla kolumny 'czas' dać właściwość KEY? Czy tworzyć jakąś osobną kolumnę, która zindexuje kolumnę czas?
I do co archiwalnych - ew. możnaby po jakimś czasie zamiast wywalać stare wpisy, wrzucać je do tabeli z archiwalnymi meczami - aby nie spowalniać działania tabeli z nowymi wydarzeniami meczów, tylko że ta archiwalna tabela w krótkim czasie byłaby starsznie ciężka smile.gif
mike
Jak będziesz miał 10 000 meczów a do kazdego 1000 zdarzeń to będziesz mógł zastanowić się czy baza da radę.
Ilości, o których wspominasz to "pierdnięcie" dla bazy danych.

Jeśli chodzi o czas to daj zwykłe pole TIMESTAMP. Przecież znająć czas zdarzenia i czas rozpoczęcia meczu możesz okreslić czas kiedy od rozpoczęcia meczu zdarzyło się coś.
Apocalyptiq
Ale ten czas będę wyliczał na oko - w zależności od długości trwania akcji. I będzie on w bazie po to, aby AJAX wiedział w którym momencie do której akcji przesłać raport na stronę (np. jest 19:00:34, a w bazie wydarzenia z czasami kolejno: 20, 30, 45, to w tym momencie AJAX wyciągnąłby pierwsze dwa wydarzenia - cały mecz o 19:00 wygeneruje PHP, a później tylko AJAX co chwilę będzie wrzucał na stronę nowe akcje, aby wyglądało to jak prawdziwy mecz smile.gif
mike
Programowanie to szukanie najprostszego rozwiązania. Odnosze wrażenie, że komplikujesz sobie życie.
Jaki związek z tym jak zapiszesz dane ma to jak je będziesz prezentował?

Jeśłi dasz wartości jako TIMESTAMP to będziesz mógł wyświetlać dane w dowolny sposób. Nie za bardzo czaję o co Ci chodzi :-)
Apocalyptiq
A timestamp to czas w jakim formacie? Nie milisekundy liczone od bodajrze 1 sty 1970r.? I jeżeli chciałbym zapisać coś, że się niby wydarzyło o 19:23:20, to po prostu taką godzinę wpisuję? A później, żeby obliczyć różnicę między aktualnym czasem a czasem wystąpienia wydarzenia, korzystam z strtotime()?
I jak najwydajniej zapisywać poszczególne wydarzenia w danej akcji - tj. serw, odbiór itp. - miałem zamiar po prostu w kolumnie events wrzucać oddzielane przecinkami skróty poszczególnych akcji, np. 1s2,2o1,2w3,2a5 . Ale na jednym forum powiedziano mi, że przecinki (i później explodowanie tego) nie są dobrym rozwiązaniem. Jest jakieś lepsze?
mike
Cytat(Apocalyptiq @ 16.10.2008, 23:19:18 ) *
A timestamp to czas w jakim formacie? Nie milisekundy liczone od bodajrze 1 sty 1970r.?
TIMESTAMP
Timestamp w PHP to co innego niż Timestamp w MySQL
Cytat(Apocalyptiq @ 16.10.2008, 23:19:18 ) *
I jak najwydajniej zapisywać poszczególne wydarzenia w danej akcji - tj. serw, odbiór itp. - miałem zamiar po prostu w kolumnie events wrzucać oddzielane przecinkami skróty poszczególnych akcji, np. 1s2,2o1,2w3,2a5 . Ale na jednym forum powiedziano mi, że przecinki (i później explodowanie tego) nie są dobrym rozwiązaniem. Jest jakieś lepsze?
No przecież pytałeś o to w pierwszym poście i już Ci odpowiedziałem. Oddzielna tabela zdarzeń (jedna dla wszystkich meczów) i każde zdarzenie jest jednym wierszem.
Apocalyptiq
Aha, ale ja chciałem nie rozbijać akcji aż tak - tj. jeden rekord = wszystkie wydarzenia w danej akcji (do zdobycia punkta).
Bo jak rozbiłbym wydarzenia aż tak, że jedno zdarzenie to np. wystawienie, to tak: skrypt PHP o tej np. 19 wygeneruje mi i zapisze w bazie cały mecz, zdarzenie po zdarzeniu. I teraz po tej 19 stopniowo na stronie będą się kolejne akcje pokazywać - AJAX + setInterval. To gdy te akcje będą za częste, może być tak, że za każdym odświeżeniem nie pokaże się 1, ale ze 2 albo 3 wydarzenia - tj. np: serw - odbiór, wystawa - przebicie nieudane, serw nieudany . Chyba że ustawić setInterval na bardzo małą wartość - tj. np co 2 sekundy odświeżanie - tylko czy wtedy bardzo przeglądarka nie zwolni?
Macie jakieś pomysły jak to najlepiej zorganizować?

Wymyśliłem sposób, w którym nie trzebaby tworzyć tej tablicy z wydarzeniami, i oszczędziłby roboty ajax'owi smile.gif A więc: wszystkie wydarzenia wyprzecinkowane daje do kolumny "events" w tabeli mecze. Gdy ktoś wejdzie na owy mecz - PHP wysyła na tą strone wynik do danej godziny, i wszystkie wydarzenia, które wydarzą się później. W JS exploduje te wydarzenia (string.split(",") ), i z odpowiednim opóźnieniem (setTimeout) odpalam na stronie. Tylko że jest tego jeden mały minus - jeżeli ktoś zajrzy w źródło strony, do części <script> - odczyta tam zakodowane (w skrótach) wszystkie wydarzenia danego meczu, nawet te, które na stronie jeszcze nie zostały wyświetlone. Ale stosując to rozwiązanie nie musiałbym się martwić o pobieranie co kilka sekund nowych wydarzeń itp. Tylko czy takie rozwiązanie będzie ok? W polu events w takim wypadku dałbym rodzaj danych - TEXT - chyba ma spory limit, co do ilości znaków (na jakimś ang forum pisali, że 65535 bajtów) smile.gif To może ustwaiłbym w jakimś prostszym kodowaniu niż utf-8 (w utf-8 chyba jeden znak zajmuje więcej niż bajt?), żeby mniej to zajmowało - i tak w skrótach nie będzie polskich znaków. I wie może ktoś, jak można te dane przesłane do JS zaszyfrować, żeby użytkownicy nie mogli nawet w źródle zobaczyć skrótów poszczególnych wydarzeń?
Proszę o komentarze co do tego sposobu.

Tak zacząłem przygotowywać się do zrobienia tego meczu tym przesłaniem wszystkich wydarzeń do JS - ale wtedy np. za pomocą FireBuga użytkownik, jeżeliby pokombinował, mógłby sobie wyświetlić cały mecz, zanim ten u przeciętnego użytkownika by się wyświetlił.
Macie może jakieś pomysły, jak to wyświetlanie meczu (poszczególnych raportów) zorganizować?

Spróbowałem sposobu z tabelą events - każde wydarzenie osobno. I jeden mecz generuje około 900 wpisów do tabeli events blinksmiley.gif Na pewno to nie zawali bazy? Z takim rozwiązaniem musiałbym chyba dosyć często usuwać wydarzenia ze starszych meczów.
No i tu zastosowałbym AJAXA - pobierałby wszystkie wydarzenia które 'już sie wydarzyły', i pobiera czas, za jaki wystąpi następne wydarzenie - i ten czas przekazuje do setTimeout - następnego wywołania requesta AJAXa.

Jeżeli macie jakieś lepsze pomysły jak to zorganizować, piszcie! Będę wdzięczny za jakieś pomysły smile.gif

Przetestowałem ten sposób razem z AJAXem (pobieranie requestami z bazy kolejnych wydarzeń co kilka sekund) - i na stronie ładnie to wygląda, co kilka sekund pojawia mi się kolejne wydarzenie. Może po prostu wydarzenia starszych meczów będę wywalał, albo ew. do jakiejś archiwalnej tabeli zapisywał.

Dzięki wszystkim za rady!
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.