Najlepszy typ danych do przechowywania wartości waluty w bazie danych MySQL

Jaki jest najlepszy typ danych SQL dla wartości waluty? Używam MySQL, ale wolałbym niezależny od bazy danych typ.

Author: John Slegers, 2009-03-10

9 answers

Coś w rodzaju Decimal(19,4) zazwyczaj działa całkiem dobrze w większości przypadków. Możesz dostosować skalę i precyzję do potrzeb liczb, które musisz przechowywać. Nawet w SQL serverze zazwyczaj nie używam "money", ponieważ jest to niestandardowe.

 217
Author: Kibbee,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-04-28 10:12:25

Jedyną rzeczą, na którą musisz uważać, jest to, że migracja z jednej bazy danych do drugiej może okazać się, że DECIMAL(19,4) i DECIMAL(19,4) oznaczają różne rzeczy

( http://dev.mysql.com/doc/refman/5.1/en/precision-math-decimal-changes.html )

    DBASE: 10,5 (10 integer, 5 decimal)
    MYSQL: 15,5 (15 digits, 10 integer (15-5), 5 decimal)
 47
Author: SeanJA,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-03-10 02:13:16

Ważne jest również, aby ustalić, ile miejsc po przecinku może być wymagane do obliczeń.

Pracowałem nad aplikacją o cenie akcji, która wymagała obliczenia ceny miliona akcji. Notowana cena akcji musiała być zapisana z dokładnością do 7 cyfr.

 17
Author: Leah,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-03-10 02:34:09

Odpowiedź Assafa

Zależy ile masz pieniędzy...

Brzmi niepoważnie, ale tak naprawdę to jest niepokojące.

Dopiero dzisiaj mieliśmy problem, w którym rekord nie został wstawiony do naszej tabeli stawek, ponieważ jedna z kolumn (GrossRate) jest ustawiona na dziesiętne (11,4), a nasz dział produktów właśnie dostał kontrakt na pokoje w jakimś niesamowitym kurorcie w Bora Bora, które sprzedają się za kilka milionów franków na Pacyfik za noc... coś, co nigdy nie było antycypowane kiedy schemat bazy danych został zaprojektowany 10 lat temu.

 17
Author: Scott Ferguson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-10-27 18:13:53

W aplikacjach księgowych bardzo często zapisuje się wartości jako liczby całkowite(niektórzy nawet mówią, że jest to tylko ). Aby uzyskać pomysł, weź kwotę transakcji (Załóżmy, że $100.23) i wielokrotność przez 100, 1000, 10000, itp. aby uzyskać dokładność, której potrzebujesz. Więc jeśli tylko trzeba przechowywać centów i można bezpiecznie zaokrąglać w górę lub w dół, po prostu pomnożyć przez 100. W moim przykładzie oznaczałoby to 10023 jako liczbę całkowitą do przechowywania. Zaoszczędzisz miejsce w bazie danych i porównasz dwa liczba całkowita jest dużo łatwiejsza niż porównywanie dwóch pływaków. Moje $0.02.

 10
Author: Dane Bendixen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-08-24 04:52:15

Super późne wejście, ale GAAP to dobra zasada..

Jeśli Twoja aplikacja musi obsługiwać wartości pieniędzy do biliona, powinno to działać: 13,2 jeśli musisz przestrzegać GAAP (ogólnie przyjętych zasad rachunkowości), użyj: 13,4

Zazwyczaj należy zsumować wartości pieniędzy na 13,4 przed zaokrągleniem wyjścia do 13,2.

Source: najlepszy typ danych do przechowywania wartości pieniężnej w MySQL

 7
Author: Damian,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 10:31:02

Możesz użyć czegoś w rodzaju DECIMAL(19,2) domyślnie dla wszystkich wartości pieniężnych, ale jeśli kiedykolwiek będziesz przechowywać wartości niższe niż $1,000, to będzie to po prostu strata cennej przestrzeni w bazie danych.

Dla większości implementacji, DECIMAL(N,2) byłoby wystarczające, gdzie wartość N jest co najmniej liczbą cyfr przed . największej sumy, jakiej spodziewasz się zapisać w tym polu + 5. Więc jeśli nigdy nie spodziewasz się przechowywać wartości większych niż 999999.99, DECIMAL(11,2) powinien być więcej niż wystarczające (dopóki oczekiwania się nie zmienią).

Jeśli chcesz być GAAP zgodny, można przejść do DECIMAL(N,4), gdzie wartość N jest co najmniej liczbą cyfr przed . największej sumy, jakiej spodziewasz się zapisać w tym polu + 7.

 5
Author: John Slegers,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-03-08 00:05:41

To zależy od rodzaju danych. Musisz to wcześniej przemyśleć.

Moja sprawa

  • dziesiętny (13,4) niepodpisany do rejestrowania transakcji pieniężnych
    • storage efficient (4 bajty dla każdej strony punktu dziesiętnego) 1
    • zgodny z GAAP
  • dziesiętne(19,4) niepodpisane dla agregatów
    • potrzebujemy więcej miejsca na sumy wielu wielomiliardowych transakcji
    • semi-zgodność z typem danych MS Currency nie hurt 2
    • zajmie to więcej miejsca na rekord (11 bajtów - 7 w lewo i 4 w prawo), ale jest to w porządku, ponieważ jest mniej rekordów dla agregatów 1
  • dziesiętne (10,5) dla kursów walut
    • są zwykle cytowane z 5 cyframi, więc można znaleźć wartości takie jak 1.2345 i 12.345, ale nie 12345.67890
    • Jest to powszechna konwencja, ale nie skodyfikowany standard (przynajmniej do mojej wiedzy szybkiego wyszukiwania)
  • you could make it decimal (18,9) z tym samym magazynem, ale ograniczenia typu danych są cenne wbudowany mechanizm walidacji

Dlaczego (M, 4)?

  • są waluty, które dzielą się na tysiąc groszy
  • istnieją ekwiwalenty pieniędzy, takie jak "Unidad de Fermento", " CLF " wyrażone z 4 znaczącymi miejscami po przecinku3,4
  • jest zgodny z GAAP

Tradeoff

  • mniejsza precyzja:
    • mniej pamięci koszt
    • szybsze obliczenia
    • mniejsze ryzyko błędu obliczeniowego
    • szybsze tworzenie kopii zapasowych i przywracanie
  • [[6]}wyższa precyzja:
    • zgodność przyszłości (liczby mają tendencję do wzrostu)
    • Oszczędność czasu rozwoju (nie będziesz musiał odbudowywać połowy systemu, gdy limity zostaną spełnione)]}
    • mniejsze ryzyko niepowodzenia produkcji z powodu niewystarczającej precyzji przechowywania

Compatible Extreme

Chociaż MySQL pozwala używać decimal(65,30), 31 dla skali i 30 dla precyzji wydają się być naszymi ograniczeniami, jeśli chcemy pozostawić otwartą opcję transferu.

Maksymalna skala i precyzja w najbardziej popularnych RDBMS:

            Precision   Scale
Oracle      31          31
T-SQL       38          38
MySQL       65          30
PostgreSQL  131072      16383

6, 7, 8, 9

Reasonable Extreme

  1. Dlaczego (27,4)?
    • nigdy nie wiadomo, kiedy system musi przechowywać pieniądze
Wrzesień 2015 Dolarów Zimbabwe dla dolarów amerykańskich po kursie od 1 USD do 35 bilionów dolarów Zimbabwe 5

Mamy tendencję do powiedzenia "tak, jasne... Nie będę potrzebował tych szalonych liczb". Zimbabwe też tak mawiało. Nie tak dawno temu.

Wyobraźmy sobie, że musisz zarejestrować transakcję 1 mln USD W dolarów Zimbabwe (może mało prawdopodobne dzisiaj, ale kto wie, jak to będzie wyglądać za 10 lat?).

  1. (1 mln USD) * (35 kwadrylion ZWL) = (10^6 ) * (35 * 10^15) = 35 * 10^21
  2. potrzebujemy:
    • 2 cyfry do zapisania "35"
    • 21 cyfr do zapisania zer
    • 4 cyfry na prawo od punktu dziesiętnego
  3. to sprawia, że dziesiętny (27,4), który kosztuje nas 15 bajtów za każdy wpis
  4. możemy dodać jedną cyfrę po lewej stronie bez żadnych kosztów - mamy dziesiętne (28,4) dla 15 bajtów
  5. Teraz możemy przechować 10 mln USD transakcji wyrażonych w dolarach Zimbabwe, lub zabezpieczyć się przed kolejnym strajkiem hiperinflacja, która miejmy nadzieję nie nastąpi
 2
Author: kshishkin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-04-01 04:43:48

Choć to może być późno, ale to będzie pomocne dla kogoś innego.Z mojego doświadczenia i badań poznałem i akceptuję dziesiętne(19, 6).Tak jest podczas pracy z php i mysql. przy pracy z dużą ilością pieniędzy i kursem walut

 0
Author: precious,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-05 07:43:26