![]() |
![]() ![]() |
![]() |
![]()
Post
#1
|
|
Grupa: Zarejestrowani Postów: 19 Pomógł: 3 Dołączył: 25.03.2009 Ostrzeżenie: (0%) ![]() ![]() |
Witam,
Aktualnie rozplanowuje na kartce swój najnowszy projekt i bardzo staram się dopiąć każdy element już podczas planowania by zaoszczędzić potem czasu i nerwów gdy będę to wszystko przekładał na kod. Podczas planowania mam pewien problem do rozgryzienia i mam nadzieję, że pomożecie. Planuje stworzyć portal gdzie każdy z użytkowników po zarejestrowaniu będzie posiadał własne adresy, dokumenty oraz inne dane, które będą zapisywane w tabelach mySQL. Zakładam, że liczba rekordów dla jednego użytkownika będzie bardzo duża, na oko ponad milion. I teraz zastanawiam się czy stworzyć jedną bazę ogólną z tabelkami i w niej przechowywać wszystkie dane każdego z użytkowników. Boje się tylko, że wtedy taka tabela może mieć naprawdę sporo rekordów (np. 100 użytkowników * 1mln rekordów = 100mln rekordów!!!) co sprawi, że szybkość działania portalu bardzo drastycznie się zmniejszy. Pomysł jaki mi wpadł do głowy to podczas rejestracji nowego użytkownika tworzyć nową bazę danych dla niego a w niej wszystkie tabelki. Wtedy jedna tabelka posiadała by maks 1mln rekordów a nie 100mln jak w poprzednim rozwiązaniu. Według mnie będzie to bardziej optymalne rozwiązanie jeżeli chodzi o szybkość działania portalu. Czy ktoś z Was próbował już coś takiego zrobić? Czy moje myślenie jest poprawne? Czy rozdzielenie użytkowników tak by każdy posiadał własną bazę jest dobrym pomysłem? Czy aby na pewno tym rozwiązaniem zwiększę szybkość działania systemu? Z góry dziękuję za pomoc! |
|
|
![]()
Post
#2
|
|
Grupa: Zarejestrowani Postów: 71 Pomógł: 1 Dołączył: 21.01.2013 Ostrzeżenie: (0%) ![]() ![]() |
Pomysł z tworzeniem osobnej bazy dla każdego użytkownika z osobna jest bardzo radykalny i abstrakcyjny. Przede wszystkim, odpada możliwość pracy na danych wielu użytkowników, gdyż tworzenie 100 połączeń dla 100 różnych użytkowników dopiero może obciążyć wykonanie skryptu php.
Wbrew pozorom, milion rekordów dla współczesnych serwerów to bułka z masłem. Oczywiście, najważniejsze jest odpowiednie zaplanowanie bazy przed jej utworzeniem (nigdy na odwrót!). O takich rzeczach jak stringi przechowywane w varchar'ach o odpowiedniej długości, czy też liczby o typie stosownym do ich maksymalnej wielkości chyba nie muszę wspominać, bo to jest raczej oczywiste. To o czym powinieneś pomyśleć, to przede wszystkim INDEKSY. Dobrze założone potrafią zdziałać cuda, nawet przy największych wydawać by się mogło bazach. Trudno jest udzielić jakichś bardziej szczegółowych porad nie wiedząc co chcesz w tej bazie zapisać, ani jakie operacje na danych wykonywać. Może da się coś skrócić, bo milion rekordów na dane użytkownika to naprawdę bardzo dużo - zastanów się, czy rzeczywiście nie da się tej ilości zmniejszyć. Poczytaj też o testach wydajnościowych MySQL, a najlepiej przeprowadź własne testy obciążeniowe. |
|
|
![]()
Post
#3
|
|
Grupa: Zarejestrowani Postów: 19 Pomógł: 3 Dołączył: 25.03.2009 Ostrzeżenie: (0%) ![]() ![]() |
Dzięki za kilka cennych rad.
Mam jeszcze jedno pytanie ponieważ słyszałem, że jeżeli naprawdę chcemy zoptymalizować przechowywanie dużej ilości rekordów i operacji na nich to pomimo tego co nas nauczono powinniśmy powtarzać w tabelach dane zamiast pobierać ich po indeksach. Zaraz postaram się to wytłumaczyć na przykładzie bo tak z czystej teorii może to być nie jasne. Załóżmy mamy 2 tabele Użytkownicy i Konto. I teraz tak jak nas nauczano powinniśmy je zaprojektować w takim stylu:
Mi zostało polecone, że gdy wiemy, że często potrzebne będzie nam oprócz wszystkich wartości z konta również nazwisko posiadacza konta to żeby duplikować dane bo to ponoć poprawi wydajność. Czyli tabelki powinny wyglądać tak:
Powyżej jest to tylko przykład. Czy ktoś z Was stosował takie rozwiązanie już? Czy jest to na pewno szybsze rozwiązanie? Dodatkowo jeszcze jedno pytanko, poleci ktoś jakieś ciekawe artykuły na temat optymalizacji baz mysql do dużych projektów? (IMG:style_emoticons/default/biggrin.gif) Z góry dziękuję i pozdrawiam! |
|
|
![]()
Post
#4
|
|
Grupa: Zarejestrowani Postów: 71 Pomógł: 1 Dołączył: 21.01.2013 Ostrzeżenie: (0%) ![]() ![]() |
Jeśli występuje tu relacja 1 do 1, to czy nie lepiej będzie po prostu zrobić to w ten sposób:
? Sama metoda z duplikowaniem danych jest jak wyważanie otwartych drzwi: Jeżeli ta przeważająca część zapytań będzie odwoływała się tylko do tabeli Konto (bez Użytkowników), to owszem, będzie widoczne zwiększenie szybkości, ale spowoduje to masę błędów:
Na pewno nie jest to żadnym wyjściem z sytuacji i osobiście odradzam w większości (99%) przypadków. |
|
|
![]()
Post
#5
|
|
Grupa: Zarejestrowani Postów: 8 068 Pomógł: 1414 Dołączył: 26.10.2005 Ostrzeżenie: (0%) ![]() ![]() |
Jeżeli przewidujesz faktycznie tak spore ilości danych per user to tutaj wchodzi partycjonowanie, Robisz partycje wg. ID użytkownika, dzięki czemu fizycznie nadal masz 1 tabelę z ogromną ilością rekordów ale logicznie jest tych tabel tyle ile użytkowników.
Wydajność tego rozwiązania polega na tym, że silnik odwołując się po ID usera szpera tylko w "bazie" dla tego konkretnego ID, więc ew. Lock tabeli odbędzie się tylko na tej jednej partycji a nie na całej bazie. Kolejnym pkt. wydajności w takim wypadku jest wyszukiwanie. Przyklad. Baza ma 100mln rekordów czyli 100 userów. Wyszukiwanie danych pomiędzy datami dla Usera ID 55 będzie odbywało się tylko na 1mln rekordów (partycja konkretnego usera) a nie na wszystkich (100mln), analogicznie WHERE user_id IN(55,66,77) przeszuka "tylko" 3mln rekordów. Ogólnie wzrost wydajności jest bardzo duży, kosztem zajmowanego miejsca na serwerze (ale to żaden argument) i musem skonfigurowania tego poprawnie. Innym rozwiązaniem może być replikacja, gdzie replikujesz rekordy np. parzyste do jednego serwera, nieparzyste do innego, a wyszukiwanie będzie odbywało się w zależności od ID usera. Równie dobre rozwiązanie j.w. jednak dużo bardziej kosztowne i wymagające większej zabawy. |
|
|
![]() ![]() |
![]() |
Aktualny czas: 24.08.2025 - 13:34 |