sql >> Databasteknik >  >> RDS >> PostgreSQL

Pengardata på PostgreSQL med Java

NUMERIC /DECIMAL

Som Joachim Isaksson sa , vill du använda NUMERIC /DECIMAL typ, som en godtycklig precisionstyp.

Två viktiga punkter om NUMERIC /DECIMAL :

  • Läs dokumentet noggrant för att lära dig att du bör specificera skalan för att undvika standardskalan 0, vilket betyder heltalsvärden där decimalbråket avbryts. Även om detta är en av platserna där Postgres avviker från standard SQL (vilket ger dig vilken skala som helst upp till implementeringsgränsen). Så att inte specificera skalan är ett dåligt val.
  • SQL-typerna NUMERIC &DECIMAL är nära men inte identiska enligt SQL Standard. I SQL:92 , din specificerade precision för NUMERIC respekteras, medan för DECIMAL databasservern tillåts lägga till ytterligare precision utöver vad du angav. Även här avviker Postgres lite från standarden, med både NUMERIC &DECIMAL dokumenterad som likvärdig.

Villkor:

  • Precision är det totala antalet siffror i ett tal.
  • Skala är antalet siffror till höger om decimaltecknet (decimalbråket).
  • ( Precision - Skala ) =Antal siffror till vänster om decimalkomma (heltalsdel).

Var tydlig med ditt projekts specifikationer för precision och skala:

  • Stor
    Precisionen måste vara tillräckligt stor för att hantera större antal som kan behövas i framtiden. Mening... Kanske din app idag fungerar i mängder av tusentals USD men måste i framtiden utföra sammandragningsrapporter som hamnar i miljoner.
  • Liten
    För vissa redovisningsändamål kan du behöva lagra en bråkdel av ett minsta valutabelopp. Det betyder... Mer än 3 eller 4 decimaler istället för de 2 som behövs för en slant i USD .

Undvik MONEY typ

Postgres erbjuder en MONEY typ också. Det kan låta rätt, men förmodligen inte bäst för de flesta ändamål. En nackdel är det med MONEY skalan ställs in av en databasomfattande konfigurationsinställning baserat på locale . Så den inställningen kan variera farligt lätt när du byter server eller gör andra ändringar. Dessutom kan du inte styra den inställningen för specifika kolumner, medan du kan ställa in skalan för varje kolumn i NUMERIC typ. Till sist, MONEY är inte standard SQL som visas i denna lista över standard SQL-data typer . Postgres inkluderar MONEY för att underlätta för folk som porterar data från andra databassystem.

Flytta decimalkomma

Ett annat alternativ som används av vissa är att flytta decimaltecknet, och bara lagra i stora heltalsdatatyp.

Till exempel, om du lagrar USD dollar till öre, multiplicera ett givet bråktal med 100, kasta till en heltalstyp och fortsätt. Till exempel, $123,45 blir heltal 12 345.

Fördelen med detta tillvägagångssätt är snabbare exekveringstider. Operationer som sum är mycket snabba när de utförs på heltal. En annan fördel med heltal är mindre minnesanvändning.

Jag tycker att det här tillvägagångssättet är irriterande, förvirrande och riskabelt. Irriterande eftersom datorer borde fungera för oss, inte mot oss. Risk eftersom någon programmerare eller användare kan försumma att multiplicera/dividera för att konvertera tillbaka till bråktal, vilket ger felaktiga resultat. Om du arbetar i ett system utan bra stöd för korrekta bråktal kan detta tillvägagångssätt vara en acceptabel lösning.

Jag ser ingen fördel med att flytta decimalkomma när vi har DECIMAL /NUMERIC i SQL och BigDecimal i Java.

Avrundning &NaN

I appens programmering, såväl som alla beräkningar som görs på Postgres serversida, var mycket försiktig och medveten om avrundning och trunkering i decimalbråket. Och testa för oavsiktlig NaNs dyker upp.

På båda sidor, app och Postgres, undvik alltid flytande punkt datatyper för pengar fungerar. Flytpunkt är designad för prestandahastighet , men till kostnaden för noggrannhet . Beräkningar kan resultera i till synes galna extrasiffror i decimalbråket. Inte bra för ekonomiska/pengar eller andra ändamål där noggrannhet spelar roll.

BigDecimal

Ja, i Java vill du ha BigDecimal som din godtyckliga precisionstyp. BigDecimal är långsammare och använder mer minne, men kommer att lagra dina pengar korrekt. SQL NUMERIC /DECIMAL ska mappas till BigDecimal som diskuterats här och på StackOverflow .

BigDecimal är en av de bästa sakerna med Java. Jag känner inte till någon annan plattform med en liknande klass, särskilt en så välimplementerad och välslipad med stora förbättringar och korrigeringar som gjorts under åren.

Använder BigDecimal är definitivt långsammare än att använda Javas flyttalstyper , float &double . Men i appar i verkligheten tvivlar jag på att dina pengarberäkningar kommer att vara någon flaskhals. Och dessutom, vilken vill du eller dina kunder ha:den snabbaste pengaberäkningar, eller korrekta pengar beräkningar? 😉

Jag har alltid tänkt på BigDecimal som den största sleeper-funktionen i Java, den viktigaste fördelen med att använda Java-plattformen framför så många andra plattformar som saknar så sofistikerat stöd för bråktal.

Liknande fråga:Bästa datatyp för valuta



  1. MySQL flera ID-sökningar

  2. PHP förberedd uttalande infoga från en loop av data

  3. Kan Sqlalchemy fungera bra med flera bifogade SQLite-databasfiler?

  4. Främmande nyckel till sammansatt nyckel