Estymacja dysku dla bazy

Odpowiedz Nowy wątek
2020-02-14 12:56

Rejestracja: 2 lata temu

Ostatnio: 2 dni temu

0

Jak estymuje się przestrzeń dyskową dla bazy danych? Dla uproszczenia załóżmy że mam jedną tabelę z dwiema kolumnami, pierwsza typu varchar(20), druga boolean. Ktoś, coś?

Pozostało 580 znaków

2020-02-14 13:04

Rejestracja: 5 lat temu

Ostatnio: 53 minuty temu

Lokalizacja: Chorzów

1

To tak nie działa. Oczywiście PI razy drzwi coś można oszacować ale dokładnie to trzeba poznać format w jakim baza zapisuje, wielkość indeksów oraz co to za rodzaj pola char bo char może być jedno bajtowy a może być 4 i więcej bajtowy ( UTF-16, UTF-32 ... )


Projektowanie i programowanie. Hobbystycznie elektronika i audio oszołom.
edytowany 1x, ostatnio: katakrowa, 2020-02-14 13:05

Pozostało 580 znaków

2020-02-14 13:32

Rejestracja: 2 lata temu

Ostatnio: 2 dni temu

0

Ok, w takim razie załóżmy że baza to mysql, innoDb, char to utf8. Skąd wziac wielkość indeksów?

Pozostało 580 znaków

2020-02-14 13:43

Rejestracja: 4 lata temu

Ostatnio: 1 godzina temu

3
mazurro napisał(a):

Ok, w takim razie załóżmy że baza to mysql, innoDb, char to utf8. Skąd wziac wielkość indeksów?

Trzeba wiedzieć ile jest tych indeksów i jakie mają pola. Jak nie od autorów systemu to nie wiem od kogo ;-)

Powinieneś wziąć pod uwagę następujące aspekty:
1) Dane
2) Indeksy
3) Backupy - jak często, jakiego rodzaju, jak długo przechowywać
4) Logi transakcyjne
5) Przyrost danych
6) BLOBy/CLOBy :-)
7) Czy estymujesz netto, czy brutto (tj. czy estymata jest aplikacyjna czy np. uwzględnia też przestrzeń na redundancje - różne RAIDy)

Prosta formułka per tabelka:
sizeof( varchar2(20) + sizeof(boolean) + engine overhead ) * #rows * (1+growthRate)
growthRate to Twój przyrost danych.
engine overhead - tyle dodatkowo per wiersz zapisuje silnik bazodanowy, żeby wiersz zapisać

edycja:
Akurat robię specyfikacje interfejsów wymiany danych i wiem ile tych danych będzie i jakiego mniej więcej kształtu, tzn. mam tabelkę z polami:

VARCHAR2(30)
VARCHAR2(3)
VARCHAR2(40)
VARCHAR2(40)
NUMBER
NUMBER
VARCHAR2(30)
VARCHAR2(30)
VARCHAR2(20)
VARCHAR2(50)
VARCHAR2(40)
NUMBER
NUMBER
NUMBER
NUMBER

Wiem, że na wejściu tej tabelki będę miał 800M rekordów, więc moja estymata na storage dla tej tabelki wygląda:

  • 9*50 znaków (bo mam 9 pól VARCHAR2 i nie chce mi się rozdrabniać na bajty, wszak to estymata, które z założenia obarczona jest jakimś błędem)
  • 6*8 bajtów na NUMBER (co prawda nie będę miał 64bitowych wartości (bo część NUMBER to wartości słownikowe, więc raczej 1,2,3 etc.) - w każdym razie 64 bity na liczbę to całkiem sporo
  • semantyka dla VARCHAR2 na bazie to CHAR, a nie BYTE, a że bazę mam w utf32, to mnożę przez 4 bajty (znów pewna nadwyżka, bo nie każdy znak będzie na 4 bajtach)

9x50x4 + 6x8 = > 1800+48 ~ 2kb per wiersz
800M x 2kb => ~1.5 TB

W tych kalkulacjach:

  • pominąłem zupełnie narzut na bazę , ale zakładam, że zaokrąglenia w górę na typie danych rozwiąże mi ten problem z nawiązką
  • pominąłem growthRate, bo dane będę używał w trybie read only, więc nie będzie przyrostu

W estymacie mam raczej pesymistyczne podejście, ale wolę mieć więcej storage niż mniej :)

edytowany 2x, ostatnio: yarel, 2020-02-14 14:24

Pozostało 580 znaków

2020-02-14 13:56
Moderator Kariera

Rejestracja: 2 lata temu

Ostatnio: 4 dni temu

Lokalizacja: Poznań

4

Opcje są przynajmniej 3:

1) oszacować rozmiar, aczkolwiek będzie to wartość przybliżona
2) poszukać w dokumentacji i zrozumieć, jak działa zapis danych na dysku przez bazę, przy czym jest to naprawdę trudne zadanie. Kilka dni temu w tym wątku - https://4programmers.net/Forum/1654036 @yarel trochę wyjaśnił, jak wygląda wewnętrzny zapis danych w bazie. Już na pierwszy rzut oka widać, że temat łatwy nie jest. Ponadto każdy silnik, a nawet każda wersja tego samego silnika, może to robić inaczej, w MySQL masz m.in. InnoDB i MyISAM i każde z nich podejrzewam, że inaczej sobie radzi z zapisem. Ponadto jeszcze konfiguracja samej bazy, fakt istnienia indeksów itp. też może mieć wpływ na rozmiar bazy
3) Zrób eksperyment - odpal u siebie jakąś bazę, wrzuć 1000, 200000, 5000000 i 200000000 rekordów, zmierz rozmiar i wyciągnij wnioski.

Osobiście polecam podejście numer 3 - eksperymenty zawsze są rozwojowe i nawet jeśli wyniki nie będą przydatne, to i tak czegoś się nauczysz i nabierzesz trochę wprawy. Tylko jeszcze jedna uwaga - pamiętaj, że nie zawsze elementy usunięte są od razu fizycznie kasowane z dysku. Czasami są jedynie oznaczane jako skasowane (coś jakbyś w książce jedynie wykreślił pozycję ze spisu treści, ale fizycznie kartek nie wyrwał), dlatego dobrze jest upewnić się, że co pewien czas na bazie jest puszczany VACUUM. Inaczej Twoje obliczenia będą bardzo nietrafne - bo indeksów "aktywnych" będzie niewiele, ale baza na dysku będzie dość potężna.


Naczelny forumowy hejter Apple

That game of life is hard to play, I'm gonna lose it anyway
The losing card I'll someday lay, So this is all I have to say
edytowany 1x, ostatnio: cerrato, 2020-02-14 14:48
@cerrato: na wielu rzeczach się znasz. - Silv 2020-02-14 14:52
ważne jest umieć stwarzać pozory ;) - cerrato 2020-02-14 14:53
Chciałbym kiedyś wiedzieć więcej od Ciebie. - Silv 2020-02-14 14:54
To nic trudnego. Myślę, że z 80% osób tutaj ma większą wiedzę, tylko po prostu siedzą cicho. A ja dużo piszę i stąd może być błędne wrażenie, że coś wiem :D - cerrato 2020-02-14 14:57

Pozostało 580 znaków

2020-02-14 14:44

Rejestracja: 2 lata temu

Ostatnio: 2 dni temu

0

Super, dzięki za odpowiedzi. Bardzo pomocne.

Pozostało 580 znaków

2020-02-14 15:00

Rejestracja: 1 rok temu

Ostatnio: 3 godziny temu

1

Wziąć wszystkie powyższe metody i najwyższy wynik pomnożyć x 3. Powinno być ok:)

Ja bym pomnożył razy 10:P - Tomek Pycia 2020-02-14 15:20

Pozostało 580 znaków

2020-02-14 15:20

Rejestracja: 11 miesięcy temu

Ostatnio: 2 godziny temu

Lokalizacja: Miechów

4
cerrato napisał(a):

Opcje są przynajmniej 3:

1) oszacować rozmiar, aczkolwiek będzie to wartość przybliżona
2) poszukać w dokumentacji i zrozumieć, jak działa zapis danych na dysku przez bazę, przy czym jest to naprawdę trudne zadanie. Kilka dni temu w tym wątku - https://4programmers.net/Forum/1654036 @yarel trochę wyjaśnił, jak wygląda wewnętrzny zapis danych w bazie. Już na pierwszy rzut oka widać, że temat łatwy nie jest. Ponadto każdy silnik, a nawet każda wersja tego samego silnika, może to robić inaczej, w MySQL masz m.in. InnoDB i MyISAM i każde z nich podejrzewam, że inaczej sobie radzi z zapisem. Ponadto jeszcze konfiguracja samej bazy, fakt istnienia indeksów itp. też może mieć wpływ na rozmiar bazy
3) Zrób eksperyment - odpal u siebie jakąś bazę, wrzuć 1000, 200000, 5000000 i 200000000 rekordów, zmierz rozmiar i wyciągnij wnioski.

Osobiście polecam podejście numer 3 - eksperymenty zawsze są rozwojowe i nawet jeśli wyniki nie będą przydatne, to i tak czegoś się nauczysz i nabierzesz trochę wprawy. Tylko jeszcze jedna uwaga - pamiętaj, że nie zawsze elementy usunięte są od razu fizycznie kasowane z dysku. Czasami są jedynie oznaczane jako skasowane (coś jakbyś w książce jedynie wykreślił pozycję ze spisu treści, ale fizycznie kartek nie wyrwał), dlatego dobrze jest upewnić się, że co pewien czas na bazie jest puszczany VACUUM. Inaczej Twoje obliczenia będą bardzo nietrafne - bo indeksów "aktywnych" będzie niewiele, ale baza na dysku będzie dość potężna.

Do tego jeszcze dochodzi defragmentacja - czyli baza może zawierać dwa raz więcej niż same dane. Pytanie też jak duże będziesz robił transakcje i ile miejsca potrzebujesz na jakieś tempy itp. Jeśli chodzi o podejście akademickie to możesz to jakoś policzyć, jeśli chodzi o życie, to pomnóż to co ci wyjdzie razy 10 i może się zmieści.

Pozostało 580 znaków

Odpowiedz

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0