PostgreSQL
 sql >> база данни >  >> RDS >> PostgreSQL

Данни за пари в PostgreSQL с помощта на Java

NUMERIC /DECIMAL

Както каза Йоахим Исаксон , искате да използвате NUMERIC /DECIMAL тип, като тип с произволна точност.

Две важни точки относно NUMERIC /DECIMAL :

  • Прочетете документ внимателно, за да научите, че трябва да посочите мащаба, за да избегнете мащаба по подразбиране от 0, което означава цели числа, при които десетичната дроб се отрязва. Въпреки че това е едно от местата, където Postgres се отклонява от стандартния SQL (давайки ви всякакъв мащаб до лимита за внедряване). Така че липсата на уточняване на мащаба е лош избор.
  • SQL типовете NUMERIC &DECIMAL са близки, но не идентични според стандарта SQL. В SQL:92 , зададената от вас точност за NUMERIC се зачита, докато за DECIMAL на сървъра на базата данни е позволено да добави допълнителна точност извън това, което сте посочили. Тук отново Postgres се отклонява малко от стандарта, както с NUMERIC &DECIMAL документирано като еквивалент.

Условия:

  • Точността е общият брой цифри в едно число.
  • Мащабът е броят на цифрите вдясно от десетичната запетая (десетичната дроб).
  • ( Прецизност - Мащаб ) =Брой цифри вляво от десетичната запетая (цяла част).

Бъдете ясни по отношение на спецификациите на вашия проект за прецизност и мащаб:

  • Голям
    Прецизността трябва да е достатъчно голяма, за да се справи с по-големи числа, които може да са необходими в бъдеще. Което означава… Може би вашето приложение днес работи със суми от хиляди щатски долари, но в бъдеще трябва да извършва сборни отчети, които в крайна сметка достигат до милиони.
  • Малък
    За някои счетоводни цели може да се наложи да съхранявате част от най-малката валутна сума. Което означава… Повече от 3 или 4 знака след десетичната запетая вместо 2, необходими за едно пени в USD .

Избягвайте MONEY тип

Postgres предлага MONEY тип също. Това може да звучи правилно, но вероятно не е най-доброто за повечето цели. Един недостатък е този с MONEY мащабът се задава от конфигурационна настройка за цялата база данни въз основа на локал . Така че тази настройка може да варира опасно лесно, когато превключвате сървъри или правите други промени. Освен това не можете да контролирате тази настройка за конкретни колони, докато можете да зададете мащаба на всяка колона на NUMERIC Тип. И накрая, MONEY не е стандартен SQL, както е показано в този списък със стандартни SQL данни типове . Postgres включва MONEY за удобство на хората, пренасящи данни от други системи за бази данни.

Преместване на десетичната точка

Друга алтернатива, използвана от някои, е преместването на десетичната запетая и просто съхраняването в големи цели числа.

Например, ако съхранявате USD долара до стотинка, умножете всяко дадено дробно число по 100, преобразувайте в целочислен тип и продължете. Например $123,45 се превръща в цяло число 12 345.

Предимството на този подход е по-бързото време за изпълнение. Операции като sum са много бързи, когато се изпълняват върху цели числа. Друго предимство на целите числа е по-малкото използване на паметта.

Намирам този подход за досаден, объркващ и рискован. Досадно, защото компютрите трябва да работят за нас, а не срещу нас. Рисковано, защото някои програмист или потребител може да пропусне да умножи/дели, за да преобразува обратно в дробно число, давайки неправилни резултати. Ако работите в система без добра поддръжка за точни дробни числа, този подход може да бъде приемливо решение.

Не виждам никакво предимство в преместването на десетичната точка, когато имаме DECIMAL /NUMERIC в SQL и BigDecimal в Java.

Закръгляване и NaN

При програмирането на вашето приложение, както и при всички изчисления, направени от страна на сървъра на Postgres, бъдете много внимателни и имайте предвид закръгляването и отрязването в десетичната дроб. И тествайте за непреднамерени NaN изскача.

И в двете страни, приложението и Postgres, винаги избягвайте плаваща запетая типове данни за работа с пари. Плаващата запетая е предназначена за бързина на изпълнение , но на цената на точността . Изчисленията могат да доведат до привидно луди допълнителни цифри в десетичната дроб. Не е подходящ за финансови/парични или други цели, където точността има значение.

BigDecimal

Да, в Java искате BigDecimal като произволен тип точност. BigDecimal е по-бавен и използва повече памет, но ще съхранява точно вашите парични суми. SQL NUMERIC /DECIMAL трябва да съответства на BigDecimal както се обсъжда тук и на StackOverflow .

BigDecimal е едно от най-добрите неща в Java. Не знам за друга платформа с подобен клас, особено такава, която е толкова добре внедрена и усъвършенствана с големи подобрения и поправки, направени през годините.

Използване на BigDecimal определено е по-бавно от използването на типовете с плаваща запетая на Java , float &double . Но в приложенията от реалния свят се съмнявам, че вашите парични изчисления ще бъдат някакво тясно място. И освен това, какво искате вие ​​или вашите клиенти:най-бързият парични изчисления или точни парични изчисления? 😉

Винаги съм мислил за BigDecimal като най-голямата спяща функция в Java, най-важното предимство за използването на платформата Java пред толкова много други платформи, на които им липсва такава усъвършенствана поддръжка за дробни числа.

Подобен въпрос:Най-добрият тип данни за валута



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Защо PostgreSQL не връща нулеви стойности, когато условието е <> вярно

  2. Актуализирайте няколко колони, които започват с конкретен низ

  3. Проблем с accepts_nested_attributes_for в Rails 5.0.0.beta3, -api опция

  4. грешка при настройка на java String[] към подготвен израз за postgres

  5. Как Div() работи в PostgreSQL