sql >> Database teknologi >  >> RDS >> PostgreSQL

Pengedata på PostgreSQL ved hjælp af Java

NUMERIC /DECIMAL

Som Joachim Isaksson sagde , vil du bruge NUMERIC /DECIMAL type, som en vilkårlig præcisionstype.

To vigtige punkter om NUMERIC /DECIMAL :

  • Læs dokumentet omhyggeligt for at lære, at du bør angive skalaen for at undgå standardskalaen på 0, hvilket betyder heltalsværdier, hvor decimalbrøken bliver fjernet. Selvom dette er et af de steder, hvor Postgres afviger fra standard SQL (giver dig enhver skala op til implementeringsgrænsen). Så det er et dårligt valg at undlade at angive skalaen.
  • SQL-typerne NUMERIC &DECIMAL er tætte, men ikke identiske i henhold til SQL-standarden. I SQL:92 , din specificerede præcision for NUMERIC respekteres, hvorimod for DECIMAL databaseserveren har lov til at tilføje yderligere præcision ud over, hvad du har angivet. Her afviger Postgres igen en smule fra standarden, med både NUMERIC &DECIMAL dokumenteret som tilsvarende.

Vilkår:

  • Nøjagtighed er det samlede antal cifre i et tal.
  • Skala er antallet af cifre til højre for decimaltegnet (decimalbrøken).
  • ( Præcision - Skala ) =Antal cifre til venstre for decimalkomma (heltalsdel).

Vær klar over dit projekts specifikationer for præcision og skala:

  • Stor
    Præcisionen skal være stor nok til at kunne håndtere større antal, der måtte blive brug for i fremtiden. Betydning... Måske fungerer din app i dag i mængder af tusindvis af USD, men skal i fremtiden udføre roll-up rapporter, der ender i millioner.
  • Lille
    Til nogle regnskabsmæssige formål skal du muligvis gemme en brøkdel af det mindste valutabeløb. Det betyder... Mere end 3 eller 4 decimaler i stedet for de 2, der er nødvendige for en krone i USD .

Undgå MONEY type

Postgres tilbyder en MONEY type også. Det lyder måske rigtigt, men nok ikke bedst til de fleste formål. En ulempe er det med MONEY skalaen er indstillet af en konfigurationsindstilling for hele databasen baseret på locale . Så den indstilling kan nemt variere farligt, når du skifter server eller foretager andre ændringer. Desuden kan du ikke kontrollere denne indstilling for specifikke kolonner, mens du kan indstille skalaen på hver kolonne af NUMERIC type. Til sidst, MONEY er ikke standard SQL som vist i denne liste over standard SQL-data typer . Postgres inkluderer MONEY for at gøre det lettere for folk, der overfører data fra andre databasesystemer.

Flyt decimaltegnet

Et andet alternativ, der anvendes af nogle, er at flytte decimaltegnet og bare gemme i datatypen med stort heltal.

For eksempel, hvis du gemmer USD dollars til penny, multiplicer et givet brøktal med 100, kast til en heltalstype, og fortsæt. For eksempel bliver $123,45 til heltal 12.345.

Fordelen ved denne tilgang er hurtigere eksekveringstider. Operationer såsom sum er meget hurtige, når de udføres på heltal. En anden fordel for heltal er mindre hukommelsesforbrug.

Jeg finder denne tilgang irriterende, forvirrende og risikabel. Irriterende, fordi computere burde arbejde for os, ikke imod os. Risikabelt, fordi en programmør eller bruger kan undlade at gange/dividere for at konvertere tilbage til brøktal, hvilket giver forkerte resultater. Hvis du arbejder i et system uden god understøttelse af nøjagtige brøktal, kan denne fremgangsmåde være en acceptabel løsning.

Jeg kan ikke se nogen fordel ved at flytte decimaltegnet, når vi har DECIMAL /NUMERIC i SQL og BigDecimal i Java.

Afrunding og NaN

I din apps programmering såvel som i alle beregninger foretaget på Postgres-serversiden skal du være meget forsigtig og opmærksom på afrunding og trunkering i decimalbrøken. Og test for utilsigtet NaNs dukker op.

På begge sider, app og Postgres, undgå altid flydende komma datatyper for penge arbejde. Flydende komma er designet til ydelseshastighed , men på bekostning af nøjagtighed . Beregninger kan resultere i tilsyneladende skøre ekstra cifre i decimalbrøken. Ikke godt til økonomiske/penge eller andre formål, hvor nøjagtighed er vigtig.

BigDecimal

Ja, i Java vil du have BigDecimal som din vilkårlige præcisionstype. BigDecimal er langsommere og bruger mere hukommelse, men vil præcist gemme dine pengebeløb. SQL NUMERIC /DECIMAL skal kortlægges til BigDecimal som diskuteret her og på StackOverflow .

BigDecimal er en af ​​de bedste ting ved Java. Jeg kender ikke nogen anden platform med en lignende klasse, især en så velimplementeret og veludviklet med store forbedringer og rettelser lavet gennem årene.

Brug af BigDecimal er bestemt langsommere end at bruge Javas flydende kommatyper , float &double . Men i apps fra den virkelige verden tvivler jeg på, at dine pengeberegninger vil være nogen flaskehals. Og desuden, hvad ønsker du eller dine kunder:den hurtigste pengeberegninger eller præcise pengeberegninger? 😉

Jeg har altid tænkt på BigDecimal som den største sovefunktion i Java, den vigtigste fordel ved at bruge Java-platformen frem for så mange andre platforme, der mangler en sådan sofistikeret understøttelse af brøktal.

Lignende spørgsmål:Bedste datatype til valuta



  1. Får du indsat antallet af rækker for ON DUPLICATE KEY UPDATE multiple insert?

  2. Oracle indsæt hvis ikke eksisterer erklæring

  3. Hvordan sammenligner man strenge i sql ignoring case?

  4. Får Kan ikke oprette forbindelse til lokal MySQL-server via socket '/var/run/mysqld/mysqld.sock'-fejl ved opsætning af mysql-database til Ruby on Rails-appen