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

Dati di denaro su PostgreSQL utilizzando Java

NUMERIC /DECIMAL

Come ha detto Joachim Isaksson , desideri utilizzare NUMERIC /DECIMAL type, come un tipo di precisione arbitraria.

Due punti importanti su NUMERIC /DECIMAL :

  • Leggi il doc attentamente per imparare che dovresti specificare la scala per evitare la scala predefinita di 0, che significa valori interi in cui la frazione decimale viene tagliata. Anche se questo è uno dei luoghi in cui Postgres si allontana dall'SQL standard (dandoti qualsiasi scalabilità fino al limite di implementazione). Quindi non specificare la scala è una scelta sbagliata.
  • I tipi SQL NUMERIC &DECIMAL sono vicini ma non identici secondo lo standard SQL. In SQL:92 , la precisione specificata per NUMERIC è rispettato, mentre per DECIMAL il server di database può aggiungere ulteriore precisione oltre a quanto specificato. Anche in questo caso Postgres si discosta un po' dallo standard, con entrambi NUMERIC &DECIMAL documentato come equivalente.

Termini:

  • La precisione è il numero totale di cifre in un numero.
  • La scala è il numero di cifre a destra del punto decimale (la frazione decimale).
  • ( Precisione - Scala ) =Numero di cifre a sinistra della virgola decimale (parte intera).

Sii chiaro sulle specifiche del tuo progetto in termini di precisione e scala:

  • Grande
    La precisione deve essere sufficientemente grande per gestire numeri più grandi che potrebbero essere necessari in futuro. Significato... Forse la tua app oggi funziona per importi di migliaia di USD, ma in futuro dovrà eseguire rapporti cumulativi che finiscono per milioni.
  • Piccolo
    Per alcuni scopi contabili, potrebbe essere necessario memorizzare una frazione dell'importo in valuta più piccolo. Significato... Più di 3 o 4 cifre decimali anziché le 2 necessarie per un centesimo in USD .

Evita MONEY digita

Postgres offre un MONEY digitare pure. Potrebbe sembrare giusto, ma probabilmente non è il migliore per la maggior parte degli scopi. Uno svantaggio è quello con MONEY la scala è impostata da un'impostazione di configurazione a livello di database basato su locale . In modo che l'impostazione possa variare pericolosamente facilmente quando si cambia server o si apportano altre modifiche. Inoltre, non puoi controllare quell'impostazione per colonne specifiche, mentre puoi impostare la scala su ciascuna colonna di NUMERIC genere. Infine, MONEY non è SQL standard come mostrato in questo elenco di dati SQL standard tipi . Postgres include MONEY per la comodità della gente che porta i dati da altri sistemi di database.

Sposta il punto decimale

Un'altra alternativa utilizzata da alcuni è spostare il punto decimale e archiviare semplicemente un tipo di dati intero grande.

Ad esempio, se si archivia USD dollari per centesimo, moltiplica un dato numero frazionario per 100, trasformalo in un tipo intero e procedi. Ad esempio, $ 123,45 diventa il numero intero 12.345.

Il vantaggio di questo approccio sono i tempi di esecuzione più rapidi. Operazioni come sum sono molto veloci se eseguiti su numeri interi. Un altro vantaggio per gli interi è un minore utilizzo della memoria.

Trovo questo approccio fastidioso, confuso e rischioso. Fastidioso perché i computer dovrebbero funzionare per noi, non contro di noi. Rischioso perché alcuni programmatori o utenti potrebbero trascurare di moltiplicare/dividere per riconvertire in numero frazionario, dando risultati errati. Se si lavora in un sistema senza un buon supporto per numeri frazionari accurati, questo approccio potrebbe essere una soluzione alternativa accettabile.

Non vedo alcun vantaggio nello spostare la virgola decimale quando abbiamo DECIMAL /NUMERIC in SQL e BigDecimal in Java.

Arrotondamento &NaN

Nella programmazione della tua app, così come in qualsiasi calcolo effettuato sul lato server di Postgres, fai molta attenzione e fai attenzione agli arrotondamenti e ai troncamenti nella frazione decimale. E verifica la presenza di NaN spuntando.

In entrambe le parti, app e Postgres, evita sempre virgola mobile tipi di dati per il lavoro di denaro. La virgola mobile è progettata per la velocità delle prestazioni , ma a prezzo dell'accuratezza . I calcoli possono comportare cifre extra apparentemente folli nella frazione decimale. Non va bene per scopi finanziari/denaro o altri scopi in cui l'accuratezza è importante.

BigDecimal

Sì, in Java, vuoi BigDecimal come tipo di precisione arbitraria. BigDecimal è più lento e utilizza più memoria, ma memorizzerà accuratamente i tuoi importi di denaro. SQL NUMERIC /DECIMAL dovrebbe essere mappato su BigDecimal come discusso qui e su StackOverflow .

BigDecimal è una delle cose migliori di Java. Non conosco nessun'altra piattaforma con una classe simile, in particolare una così ben implementata e perfezionata con importanti miglioramenti e correzioni apportate nel corso degli anni.

Usando BigDecimal è decisamente più lento rispetto all'utilizzo di tipi a virgola mobile di Java , float &double . Ma nelle app del mondo reale dubito che i tuoi calcoli sul denaro rappresenteranno un collo di bottiglia. E inoltre, cosa volete voi o i vostri clienti:il più veloce calcoli di denaro o accurati calcoli di denaro? 😉

Ho sempre pensato a BigDecimal come la più grande funzionalità dormiente in Java, il vantaggio più importante dell'utilizzo della piattaforma Java su così tante altre piattaforme prive di un supporto così sofisticato per i numeri frazionari.

Domanda simile:Miglior tipo di dati per valuta