Voglio archiviare molti record in un database MySQL. Tutti contengono valori monetari. Ma non so quante cifre verranno inserite per ognuna.
Quale tipo di dati devo utilizzare per questo scopo?
VARCHAR o INT (o altri tipi di dati numerici)?
Voglio archiviare molti record in un database MySQL. Tutti contengono valori monetari. Ma non so quante cifre verranno inserite per ognuna.
Quale tipo di dati devo utilizzare per questo scopo?
VARCHAR o INT (o altri tipi di dati numerici)?
Risposte:
Poiché il denaro ha bisogno di una rappresentazione esatta, non utilizzare tipi di dati che sono solo approssimativi float
. È possibile utilizzare un tipo di dati numerico a virgola fissa per tale like
decimal(15,2)
15
è la precisione (lunghezza totale del valore comprese le cifre decimali)2
è il numero di cifre dopo il punto decimaleVedi i tipi numerici MySQL :
Questi tipi vengono utilizzati quando è importante preservare la precisione esatta, ad esempio con i dati monetari .
decimal
e numeric
sono gli stessi.
numeric(19,4)
per i registri finanziari che ti danno una mano migliore per giocare e adottare facilmente nuove richieste.
Puoi usare DECIMAL
o NUMERIC
entrambi sono uguali
I tipi DECIMAL e NUMERIC memorizzano valori esatti di dati numerici. Questi tipi vengono utilizzati quando è importante preservare la precisione esatta, ad esempio con i dati monetari. In MySQL, NUMERIC è implementato come DECIMAL, quindi le seguenti osservazioni su DECIMAL si applicano ugualmente a NUMERIC. : MySQL
vale a dire DECIMAL(10,2)
Preferisco usare BIGINT
e memorizzare i valori moltiplicandoli per 100 , in modo che diventino numeri interi.
Ad esempio, per rappresentare un valore in valuta di 93.49
, il valore deve essere memorizzato come 9349
, mentre viene visualizzato il valore che possiamo dividere per 100 e visualizzare. Questo occuperà meno spazio di archiviazione.
Attenzione: per lo
più non eseguiamo lacurrency * currency
moltiplicazione, nel caso in cui lo stiamo facendo quindi dividere il risultato con 100 e memorizzare, in modo che ritorni alla precisione corretta.
DECIMAL
? Crei la necessità di tradurre centesimi in dollari e guai se lo dimentichi ad un certo punto.
$0.005
o $0.12345
) perché non si ridurrà a un numero intero dopo aver moltiplicato per 100. Se si conosce la precisione dei valori è chiaro che la migliore opzione è usare DECIMAL
. Ma se non conosci la precisione (come nei miei esempi), allora ... sarebbe FLOAT
appropriato?
Dipende dalle tue necessità.
L'uso di DECIMAL(10,2)
solito è sufficiente, ma se hai bisogno di valori un po 'più precisi puoi impostare DECIMAL(10,4)
.
Se lavori con valori elevati sostituisci 10
con 19
.
Se l'applicazione deve gestire valori monetari fino a un trilione, questo dovrebbe funzionare: 13,2 Se è necessario rispettare i principi contabili generalmente accettati, utilizzare: 13,4
Di solito dovresti sommare i valori del tuo denaro a 13,4 prima di arrotondare l'output a 13,2.
In effetti, ciò si basa sulle preferenze del programmatore. Personalmente utilizzo: numeric(15,4)
per conformarmi ai Principi contabili generalmente accettati ( GAAP ) .
double
.* Gasp *
Perché può rappresentare qualsiasi numero di 15 cifre senza vincoli sulla posizione del punto decimale . Tutto per un misero 8 byte!
Quindi può rappresentare:
0.123456789012345
123456789012345.0
... e qualsiasi altra via di mezzo.
Questo è utile perché abbiamo a che fare con valute globali edouble
possiamo memorizzare i vari numeri di posizioni decimali che probabilmente incontreremo.
Un singolo double
campo può rappresentare 999.999.999.999.999 in yen giapponesi, 9.999.999.999.999,99 in dollari USA e persino 9.999.999.9999999 in bitcoin
Se si tenta di fare lo stesso con decimal
, è necessariodecimal(30, 15)
che costa 14 byte.
Certo, usando double
non è privo di avvertenze.
Tuttavia, non è una perdita di precisione come alcuni tendono a sottolineare. Anche se double
potrebbe non essere esatto internamente al sistema base 10 , possiamo renderlo esatto arrotondando il valore che estraiamo dal database ai suoi decimali significativi. Se necessario, lo è. (es. se verrà emesso, ed è richiesta la rappresentazione di base 10).
Le avvertenze sono, ogni volta che eseguiamo l'aritmetica con esso, dobbiamo normalizzare il risultato (arrotondandolo alle sue decimali significative) prima di:
Un altro tipo di avvertimento è, a differenza di decimal(m, d)
dove il database impedirà ai programmi di inserire un numero con più di m
cifre, non esistono convalide di questo tipo double
. Un programma potrebbe inserire un valore immesso dall'utente di 20 cifre e finirà per essere silenziosamente registrato come un importo impreciso.
1.410000000000
(dodici cifre decimali significative), ma moltiplicandolo per 1.000.000.000.000 (ovvero 13 cifre significative rimaste del punto decimale) significa che stiamo lavorando con almeno un combinato di 25 cifre di significato. Questo supera di gran lunga i 15 disponibili per un doppio, quindi dal punto di vista del design penso che sarebbe molto rotto.
Al momento questa domanda è stata posta nessuno pensava al prezzo di Bitcoin. Nel caso di BTC, probabilmente non è sufficiente da usare DECIMAL(15,2)
. Se il Bitcoin salirà a $ 100.000 o più, avremo almeno bisogno DECIMAL(18,9)
di supportare criptovalute nelle nostre app.
DECIMAL(18,9)
occupa 12 byte di spazio in MySQL ( 4 byte per 9 cifre ).
Conservare il denaro BIGINT
moltiplicato per 100 o più con il motivo di utilizzare meno spazio di archiviazione non ha senso in tutte le situazioni "normali".
DECIMAL(13,4)
DECIMAL
.
DECIMAL(13,4)
rappresenta 9 cifre + 4 cifre frazione (posizioni decimali) => 4 + 2 byte = 6 byteBIGINT
.Se è richiesta la conformità GAAP o sono necessarie 4 cifre decimali:
DECIMAL (13, 4) che supporta un valore massimo di:
$ 999,999,999.9999
Altrimenti, se sono sufficienti 2 cifre decimali: DECIMAL (13,2)
src: https://rietta.com/blog/best-data-types-for-currencymoney-in/
Moltiplica 10000 e memorizza come GRANDE, come "Valuta" in Visual Basic e Office. Vedi https://msdn.microsoft.com/en-us/library/office/gg264338.aspx
deimal(10,2)
è quello che uso ... puoi regolare i valori in base alle dimensioni previste