Il miglior tipo di dati per l'archiviazione dei valori di valuta in un database MySQL


Risposte:


227

Qualcosa di simile di Decimal(19,4)solito funziona abbastanza bene nella maggior parte dei casi. È possibile regolare la scala e la precisione per adattarsi alle esigenze dei numeri che è necessario memorizzare. Anche in SQL Server, tendo a non usare " money" perché non è standard.


52
Un punto sulla dimensione: secondo MSDN ( msdn.microsoft.com/en-us/library/ms187746.aspx ), Decimal (10,4) e Decimal (19,4) utilizzano entrambi 9 byte di spazio di archiviazione, quindi potrebbe bene molla per quelle 9 cifre in più di scala.
Adam Nofsinger,

1
L'articolo di MSDN riguarda SQL Server ma la domanda riguarda MySQL. (Ho incontrato sviluppatori che pensano che entrambi siano gli stessi, quindi è meglio essere chiari.)
cja

5
Qual è il vantaggio dell'utilizzo (19,4)anziché (19,2)?
ryvantage

1
Il mio vantaggio è stato questo ... Avevo bisogno di tutte le righe della mia tabella per eguagliare un determinato importo di denaro. Diciamo che l'importo è di $ 10,00. Man mano che vengono aggiunte nuove righe, ogni importo cambia. Se ci sono 3 righe nella tabella. 10/3 = 3.3333333333 ... ma con solo 2 decimali vengono memorizzati come 3,33. Quindi, quando li sommi, 3,33 + 3,33 + 3,33 = 9,99. Abbiamo perso un centesimo! Peggio ancora su un set di dati più grande. Conservare a 19,4 e sommare i totali, quindi arrotondare l'output a 19,2 ..
Rick

49

L'unica cosa a cui devi fare attenzione è che se esegui la migrazione da un database a un altro potresti scoprire che DECIMAL (19,4) e DECIMAL (19,4) significano cose diverse

( http://dev.mysql.com/doc/refman/5.1/en/precision-math-decimal-changes.html )

    DBASE: 10,5 (10 interi, 5 decimali)
    MYSQL: 15,5 (15 cifre, 10 numeri interi (15-5), 5 decimali)

Il link ora è morto, sfortunatamente.
Marco Aurélio Deleu,

1
@ MarcoAurélioDeleu - Ho cambiato il link per puntare alla pagina sulla Wayback Machine, quindi puoi vederlo come visto nel 2009.
Tony

17

È anche importante capire quante cifre decimali potrebbero essere necessarie per i tuoi calcoli.

Ho lavorato su un'applicazione di prezzo delle azioni che ha richiesto il calcolo del prezzo di un milione di azioni. Il prezzo delle azioni quotato doveva essere memorizzato a 7 cifre di precisione.


7
È un buon punto - specialmente nelle app finanziarie, il "prezzo" sicuramente non implica "soldi"
Mike Woodhouse

17

La risposta di Assaf di

Dipende da quanti soldi hai ...

sembra debole, ma in realtà è pertinente.

Solo oggi abbiamo riscontrato un problema per cui un record non è stato inserito nella nostra tabella delle tariffe, perché una delle colonne (GrossRate) è impostata su Decimale (11,4) e il nostro reparto prodotti ha appena ottenuto un contratto per le camere in un resort fantastico a Bora Bora, che vende per diversi milioni di franchi del Pacifico a notte ... qualcosa che non fu mai anticipato quando lo schema del database fu progettato 10 anni fa.


2
Ecco perché ho raccomandato il decimale (19,4). Può sembrare eccessivo, ma non si sa mai quando è necessario archiviare una quantità molto grande in quel campo.
Kibbee,

2
@Kibbee: non avrei concordato con te per i nostri requisiti fino ad oggi. (Per 6 anni (11,4) andò perfettamente bene ...)
Scott Ferguson,

@Kibbee Sembra un meme da 640 Kb :)
Nikita Bosik,

13

Per le applicazioni di contabilità è molto comune archiviare i valori come numeri interi (alcuni addirittura spingono fino a dire che è l' unico modo). Per avere un'idea, prendi la quantità delle transazioni (supponiamo che $ 100,23) e multipli per 100, 1000, 10000, ecc. Per ottenere l'accuratezza di cui hai bisogno. Quindi, se hai solo bisogno di archiviare centesimi e puoi arrotondare in modo sicuro su o giù, moltiplica per 100. Nel mio esempio, renderebbe 10023 come numero intero da memorizzare. Risparmierai spazio nel database e il confronto di due numeri interi è molto più semplice rispetto al confronto di due float. I miei $ 0,02.


Come si memorizzano 6.125 (6 1/8)?
PeterToTheThird

Immagino che lo memorizzerebbe come numero intero 6125.
Jimmy Knoot

2
Come sarebbe meglio di DECIMAL? Dovresti stare molto attento a tradurre sempre dollari, mulini o mulini in dollari, nei momenti appropriati.

Ho letto che le prestazioni sono in genere più veloci con INT rispetto a DECIMAL, anche nelle ultime versioni di MySQL. È anche più facile quando devi portare questi valori in PHP o qualcosa del genere e confrontare i valori.
Dane Bendixen,

9

ingresso super late ma GAAP è una buona regola empirica ..

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.

Fonte: miglior tipo di dati per memorizzare il valore monetario in MySQL


5

Potresti usare qualcosa di simile DECIMAL(19,2)per impostazione predefinita per tutti i tuoi valori monetari, ma se memorizzerai sempre valori inferiori a $ 1.000, questo sarà solo uno spreco di prezioso spazio nel database.

Per la maggior parte delle implementazioni, DECIMAL(N,2)sarebbe sufficiente, in cui il valore di Nè almeno il numero di cifre prima .della somma più elevata che ci si aspetta di essere memorizzato in quel campo + 5. Quindi, se non ti aspetti di memorizzare valori superiori a 999999.99, DECIMAL(11,2)dovrebbe essere più che sufficiente (fino a quando le aspettative non cambieranno).

Se vuoi essere conformi a GAAP , è possibile procedere conDECIMAL(N,4)un valore pariNalmeno al numero di cifre prima.della somma massima che si prevede di memorizzare in quel campo+ 7.


3

Dipende dalla natura dei dati. Devi contemplarlo in anticipo.

Il mio caso

  • decimale (13,4) non firmato per la registrazione di transazioni monetarie
    • archiviazione efficiente (4 byte per ogni lato del punto decimale) 1
    • Conformità GAAP
  • decimale (19,4) non firmato per aggregati
    • abbiamo bisogno di più spazio per i totali di più miliardi di transazioni
    • la semi-conformità con il tipo di dati Valuta MS non farà male 2
    • occuperà più spazio per record (11 byte - 7 a sinistra e 4 a destra), ma va bene in quanto vi sono meno record per gli aggregati 1
  • decimale (10,5) per i tassi di cambio
    • sono normalmente quotati con 5 cifre complessivamente in modo da poter trovare valori come 1.2345 e 12.345 ma non 12345.67890
    • è una convenzione diffusa, ma non uno standard codificato (almeno per le mie conoscenze di ricerca rapida)
    • potresti renderlo decimale (18,9) con lo stesso spazio di archiviazione, ma le restrizioni del tipo di dati sono un prezioso meccanismo di convalida incorporato

Perché (M, 4)?

  • ci sono valute che si dividono in mille centesimi
  • ci sono equivalenti monetari come "Unidad de Fermento", "CLF" espresso con 4 decimali significativi 3 , 4
  • è conforme a GAAP

Scambio

  • minore precisione:
    • meno costi di archiviazione
    • calcoli più rapidi
    • rischio di errore di calcolo inferiore
    • backup e ripristino più rapidi
  • maggiore precisione:
    • compatibilità futura (i numeri tendono a crescere)
    • risparmio di tempo di sviluppo (non sarà necessario ricostruire mezzo sistema quando vengono raggiunti i limiti)
    • minor rischio di guasti alla produzione a causa dell'insufficiente precisione di conservazione

Extreme compatibile

Sebbene MySQL ti permetta di usare il decimale (65,30), 31 per la scala e 30 per la precisione sembrano essere i nostri limiti se vogliamo lasciare aperta l'opzione di trasferimento.

Massima scala e precisione nei RDBMS più comuni:

            Bilancia di precisione
Oracle 31 31
T-SQL 38 38
MySQL 65 30
PostgreSQL 131072 16383

6 , 7 , 8 , 9

Estremo ragionevole

  1. Perché (27,4)?
    • non si sa mai quando il sistema deve conservare i dollari dello Zimbabwe

Settembre 2015 Il governo dello Zimbabwe ha dichiarato che cambierà dollari dello Zimbabwe con dollari statunitensi ad un tasso compreso tra 1 USD e 35 quadrilioni di dollari dello Zimbabwe 5

Tendiamo a dire "sì, certo ... non avrò bisogno di quelle figure pazze". Bene, anche lo Zimbabwe diceva questo. Non molto tempo fa.

Immaginiamo che sia necessario registrare una transazione di 1 mln di dollari in dollari dello Zimbabwe (forse oggi improbabile, ma chissà come sarà tra 10 anni?).

  1. (1 mln USD) * (35 Quadrylion ZWL) = (10 ^ 6) * (35 * 10 ^ 15) = 35 * 10 ^ 21
  2. abbiamo bisogno:
    • 2 cifre per memorizzare "35"
    • 21 cifre per memorizzare gli zeri
    • 4 cifre a destra del punto decimale
  3. questo rende decimale (27,4) che ci costa 15 byte per ogni voce
  4. possiamo aggiungere un'altra cifra a sinistra senza spese - abbiamo un decimale (28,4) per 15 byte
  5. Ora possiamo archiviare transazioni da 10 mln di dollari espressi in dollari dello Zimbabwe, o garantirci da un altro sciopero dell'inflazione, che si spera non accada

0

Anche se questo può essere in ritardo, ma sarà utile a qualcun altro. Dalla mia esperienza e ricerca ho imparato a conoscere e accettare il decimale (19, 6). Questo è quando si lavora con php e mysql. quando si lavora con grandi quantità di denaro e tasso di cambio

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.