PostgreSQL
 sql >> Baza danych >  >> RDS >> PostgreSQL

Dane finansowe w PostgreSQL przy użyciu Javy

NUMERIC /DECIMAL

Jak powiedział Joachim Isaksson , chcesz użyć NUMERIC /DECIMAL typ, jako typ dowolnej precyzji.

Dwie ważne kwestie dotyczące NUMERIC /DECIMAL :

  • Przeczytaj dokument ostrożnie, aby dowiedzieć się, że należy określić skalę, aby uniknąć domyślnej skali 0, co oznacza wartości całkowite, w których ułamek dziesiętny jest obcinany. Chociaż jest to jedno z miejsc, w których Postgres odchodzi od standardowego SQL (daje dowolną skalę do limitu implementacji). Więc brak określenia skali jest złym wyborem.
  • Typy SQL NUMERIC &DECIMALbliskie, ale nie identyczne zgodnie ze standardem SQL. W SQL:92 , określona precyzja dla NUMERIC jest przestrzegany, podczas gdy dla DECIMAL serwer bazy danych może zwiększyć precyzję poza określoną przez użytkownika. Tutaj ponownie Postgres nieco odbiega od standardu, z obiema wartościami NUMERIC &DECIMAL udokumentowane jako odpowiednik.

Warunki:

  • Precyzja to całkowita liczba cyfr w liczbie.
  • Skala to liczba cyfr na prawo od przecinka dziesiętnego (ułamek dziesiętny).
  • ( Dokładność - Skala ) =Liczba cyfr na lewo od przecinka dziesiętnego (część całkowita).

Jasno określ specyfikacje projektu dotyczące precyzji i skali:

  • Duży
    Precyzja musi być wystarczająco duża, aby obsłużyć większe liczby, które mogą być potrzebne w przyszłości. To znaczy… Być może Twoja aplikacja działa dziś na kwoty tysięcy USD, ale w przyszłości będzie musiała wykonywać raporty zbiorcze, które kończą się milionami.
  • Mały
    W niektórych celach księgowych może być konieczne przechowywanie ułamka najmniejszej kwoty w walucie. To znaczy… Więcej niż 3 lub 4 miejsca po przecinku zamiast 2 potrzebne do grosza w USD .

Unikaj MONEY wpisz

Postgres oferuje MONEY wpisz również. To może brzmieć dobrze, ale prawdopodobnie nie jest najlepsze dla większości celów. Jednym minusem jest to, że z MONEY skala jest ustawiana przez ustawienie konfiguracji obejmujące całą bazę danych na podstawie lokalizacji . To ustawienie może się niebezpiecznie łatwo zmieniać, gdy zmieniasz serwery lub wprowadzasz inne zmiany. Co więcej, nie możesz kontrolować tego ustawienia dla określonych kolumn, podczas gdy możesz ustawić skalę dla każdej kolumny NUMERIC rodzaj. Na koniec MONEY nie jest standardowym SQL, jak pokazano na tej liście standardowych danych SQL typy . Postgres zawiera MONEY dla wygody osób przenoszących dane z innych systemów baz danych.

Przesuń punkt dziesiętny

Inną alternatywą stosowaną przez niektórych jest przesuwanie przecinka dziesiętnego i po prostu przechowywanie danych w dużych liczbach całkowitych.

Na przykład, jeśli przechowujesz USD dolarów do grosza, pomnożyć dowolną liczbę ułamkową przez 100, odrzucić na typ liczby całkowitej i kontynuować. Na przykład 123,45 USD staje się liczbą całkowitą 12 345.

Zaletą tego podejścia jest szybszy czas realizacji. Operacje takie jak sum są bardzo szybkie, gdy są wykonywane na liczbach całkowitych. Kolejną korzyścią dla liczb całkowitych jest mniejsze zużycie pamięci.

Uważam, że takie podejście jest irytujące, mylące i ryzykowne. Irytujące, ponieważ komputery powinny działać dla nam, nie przeciwko nam. Ryzykowne, ponieważ niektórzy programiści lub użytkownicy mogą zaniedbywać mnożenie/dzielenie w celu konwersji z powrotem do liczby ułamkowej, dając nieprawidłowe wyniki. Jeśli pracujesz w systemie bez dobrej obsługi dokładnych liczb ułamkowych, to podejście może być akceptowalnym obejściem.

Nie widzę żadnej korzyści z przesuwania kropki dziesiętnej, gdy mamy DECIMAL /NUMERIC w SQL i BigDecimal w Javie.

Zaokrąglanie i NaN

W programowaniu Twojej aplikacji, a także we wszelkich obliczeniach wykonywanych po stronie serwera Postgres, bądź bardzo ostrożny i pamiętaj o zaokrąglaniu i obcinaniu w ułamku dziesiętnym. I przetestuj pod kątem nieumyślnych NaN wyskakuje.

Po obu stronach, w aplikacji i Postgresie, zawsze unikaj zmiennego punktu typy danych do pracy z pieniędzmi. Liczba zmiennoprzecinkowa została zaprojektowana z myślą o szybkości wydajności , ale kosztem dokładności . Obliczenia mogą skutkować pozornie szalonymi dodatkowymi cyframi w ułamku dziesiętnym. Nie nadaje się do celów finansowych/finansowych lub innych, w których liczy się dokładność.

BigDecimal

Tak, w Javie chcesz BigDecimal jako arbitralny typ precyzji. BigDecimal jest wolniejszy i zużywa więcej pamięci, ale dokładnie przechowuje kwoty pieniędzy. SQL NUMERIC /DECIMAL powinien mapować na BigDecimal jak omówiono tutaj i na StackOverflow .

BigDecimal to jedna z najlepszych rzeczy w Javie. Nie znam żadnej innej platformy o podobnej klasie, zwłaszcza tak dobrze zaimplementowanej i dopracowanej z dużymi ulepszeniami i poprawkami wprowadzonymi przez lata.

Korzystanie z BigDecimal jest zdecydowanie wolniejszy niż używanie typów zmiennoprzecinkowych Java , float &double . Ale w rzeczywistych aplikacjach wątpię, aby twoje obliczenia finansowe były wąskim gardłem. A poza tym, czego Ty lub Twoi klienci chcecie:najszybszy obliczenia pieniężne lub dokładne obliczenia pieniędzy?

Zawsze myślałem o BigDecimal jako największa funkcja usypiająca w Javie, najważniejsza zaleta korzystania z platformy Java w porównaniu z wieloma innymi platformami, które nie mają tak zaawansowanego wsparcia dla liczb ułamkowych.

Podobne pytanie:Najlepszy typ danych dla waluty



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Data w formacie mmm rrrr w postgresql

  2. Kolumna wygenerowana przez Postgresql kończy się niepowodzeniem podczas łączenia kolumn nie zerowych

  3. PostgreSQL:znajdź liczbę kolejnych dni do tej pory

  4. używanie schematów w postgresql

  5. Jak zasymulować zakleszczenie w PostgreSQL?