Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Dużo drobnych danych - jak optymalizować
Forum PHP.pl > Forum > Bazy danych
strateg
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
Pyton_000
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.
strateg
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ć?
Pyton_000
Tu możesz poczytać o partycjonowaniu

http://db-diary.blogspot.com/2014/08/party...-mysql-v55.html
strateg
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ę.
Pyton_000
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
strateg
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 wink.gif
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.