![]() |
![]() |
![]() ![]()
Post
#1
|
|
Grupa: Zarejestrowani Postów: 9 Pomógł: 1 Dołączył: 23.12.2010 Ostrzeżenie: (0%) ![]() ![]() |
Cześć wszystkim,
Mój dzisiejszy problem jest dość nietypowy. Chciałem zrealizować system statystyk. Dla każdego użytkownika systemu byłaby generowana jedna liczba określająca postęp w danym dniu i wpisywana do bazy danych. Wpis miałby postać: id_user | date | points Chciałbym docelowo przechowywać statystyki z miesiąca, a najlepiej roku. Problemy zaczynają się, gdy zaczniemy liczyć. Załóżmy, że portal ma 10 tysięcy użytkowników. Wtedy statystyki obejmujące tylko miesiąc (starsze automatycznie kasujemy) zajmują: 100k * 30 = 3 miliony rekordów - bardzo dużo! PROBLEM Dopuszczam możliwość, że użytkowników może być znacznie więcej, albo okres przechowywania może być dłuższy. W obu przypadkach uzyskuję bazę danych, w których mam dużo rekordów przechowujących mało informacji. Wnioskuję, że wydajność tak błahego rozwiązanie będzie okropna. OPTYMALIZACJA 1 Przechowuję dane tygodniami, czyli mam rekord zawierający łącznie zapis z 7 ostatnich dni. Wtedy znacząco zmniejszam ilość rekordów, komplikuję jednak pobieranie i wstawianie danych, które robią się nieoczywiste. Opcji z miesięcznym rekordem (30 pól) nawet nie biorę pod uwagę. OPTYMALIZACJA 2 Kompresuję dane do formatu JSON i w ten sposób dla każdego rekordu przechowuję dowolną ilość dni. Rozmiar takich danych nie jest tragiczny, a ilość rekordów jest już minimalna. Pobieranie - żaden problem. Modyfikacja będzie wymagała aktualizacji przynajmniej 1/24 rekordów (robię to dla każdej strefy czasowej). Wtedy mogę użyć jakieś "inteligentnego JOINA" z operacją na łańcuchach i pośrednio zaleczyć problem. Usuwanie starych dni jest jednak problematyczne: muszę wczytywać osobno każdy rekord, modyfikować go w skrypcie i odsyłać - masakra. OPTYMALIZACJA 3 Podobny sposób, jak w wersji 2, jednak w danym rekordzie pilnuję, aby była informacja tylko o konkretnej ilości dni (np. miesiąc). Wtedy w razie potrzeby pobieram odpowiednią ilość rekordów (max 2 dla okresu miesięcznego) i jest fajnie. Regularnie usuwam rekordy ze zbyt starą informacją (starsze niż miesiąc). Oczywiście 30 dni można zamienić na dowolną ilość dni. PODSUMOWANIE CO o tym sądzicie? Macie jakieś lepsze pomysły/metody? Jak realizujecie takie problemy? Pozdrawiam, Marcin Ten post edytował strateg 10.09.2014, 19:45:58 |
|
|
![]() |
![]()
Post
#2
|
|
![]() Grupa: Zarejestrowani Postów: 8 068 Pomógł: 1414 Dołączył: 26.10.2005 Ostrzeżenie: (0%) ![]() ![]() |
3mln rekordów twojego typu to nie jest dużo, tym bardziej że rozmiar pojedynczego rekordu oszacujemy na ok 24 bajty + rozmiar klucza czyli ok 32 bajty. Pikuś.
Zrób sobie taką tabelkę dla testów i zobaczysz jak wydajność będzie się trzymać. Raczej sugerowałbym zostanie przy 1 rekord - 1 wpis. Możesz zastosować partycjonowanie tabeli po ID użytkownika (zakres np. 1tyś użytkowników/partycja), dzięki czemu uzyskasz "mniejsze" tabelki i gigantyczny wzrost wydajności przy przeszukiwania dla konkretnego użytkownika, bo wtedy silnik bierze konkretną partycję i szuka tylko w 1 tyś użytkowników. |
|
|
![]()
Post
#3
|
|
Grupa: Zarejestrowani Postów: 9 Pomógł: 1 Dołączył: 23.12.2010 Ostrzeżenie: (0%) ![]() ![]() |
Czyli jednak najprostsze rozwiązania są najlepsze. Nie ukrywam, że dla mnie takie rozwiązanie byłoby oczywiście preferowane. A co jeśli będę miał znacznie więcej danych, powiedzmy 50 milionów rekordów (myślę o rocznej żywotności statystyk i większej ilości użytkowników). Wtedy dalej ma to sens?
Oczywiście klucz nakładam na id_użytkownika, tylko po nim przeszukuję wpisy. Następna kwestia to partycjonowanie. Czy pomimo obecność klucza, powinienem je wykonywać? Ten post edytował strateg 10.09.2014, 19:46:45 |
|
|
![]()
Post
#4
|
|
![]() Grupa: Zarejestrowani Postów: 8 068 Pomógł: 1414 Dołączył: 26.10.2005 Ostrzeżenie: (0%) ![]() ![]() |
|
|
|
![]()
Post
#5
|
|
Grupa: Zarejestrowani Postów: 9 Pomógł: 1 Dołączył: 23.12.2010 Ostrzeżenie: (0%) ![]() ![]() |
OK, bardzo dziękuję za link, już się biorę do lektury. Po prostu tak wielkie liczby trochę mnie przerażają, a tu jednak nie ma czego się bać ;p Jak dojdę do jakichś wnioskó - oczywiście napiszę.
|
|
|
![]()
Post
#6
|
|
![]() Grupa: Zarejestrowani Postów: 8 068 Pomógł: 1414 Dołączył: 26.10.2005 Ostrzeżenie: (0%) ![]() ![]() |
Najlepszą metodą jest przetestowanie namacalnie takich rzeczy.
Ostatnio pisząc co nie co w Laravel trafiłem na fajna bibliotekę co się zowie Faker do generowania danych. https://github.com/fzaninotto/Faker |
|
|
![]()
Post
#7
|
|
Grupa: Zarejestrowani Postów: 9 Pomógł: 1 Dołączył: 23.12.2010 Ostrzeżenie: (0%) ![]() ![]() |
Dzięki, że dałeś mi do zrozumienia, że JSON nie jest najlepszym pomysłem. Trochę byłoby męczenia się z nim, a to wszystko w sumie niepotrzebne
![]() |
|
|
![]() ![]() |
![]() |
Wersja Lo-Fi | Aktualny czas: 14.08.2025 - 04:28 |