Bester Datentyp zum Speichern von Währungswerten in einer MySQL-Datenbank

Antworten:

227

So etwas Decimal(19,4)funktioniert normalerweise in den meisten Fällen ziemlich gut. Sie können den Maßstab und die Präzision an die Anforderungen der zu speichernden Zahlen anpassen. Selbst in SQL Server verwende ich normalerweise nicht " money", da dies nicht dem Standard entspricht.

Kibbee
quelle
52
Ein Punkt zur Größe: Laut MSDN ( msdn.microsoft.com/en-us/library/ms187746.aspx ) verwenden Decimal (10,4) und Decimal (19,4) jeweils 9 Byte Speicherplatz Nun, Frühling für diese zusätzlichen 9 Ziffern.
Adam Nofsinger
1
Der MSDN-Artikel befasst sich mit SQL Server, aber die Frage bezieht sich auf MySQL. (Ich habe Entwickler getroffen, die denken, dass beide gleich sind, um klar zu sein.)
cja
5
Was ist der Vorteil (19,4)anstelle von (19,2)?
Ryvantage
1
Mein Vorteil war dies. Ich brauchte alle meine Tabellenzeilen, um einem bestimmten Geldbetrag zu entsprechen. Angenommen, der Betrag beträgt 10,00 USD. Wenn neue Zeilen hinzugefügt werden, ändert sich jede Zeilenmenge. Wenn die Tabelle 3 Zeilen enthält. 10/3 = 3.3333333333 ... aber mit nur 2 Dezimalstellen werden sie als 3.33 gespeichert. Wenn Sie diese zusammenfassen, ist 3,33 + 3,33 + 3,33 = 9,99. Wir haben einen Cent verloren! Wird bei einem größeren Datensatz noch schlimmer. Speichern Sie bei 19,4 und summieren Sie Ihre Summen, dann runden Sie die Ausgabe auf 19,2 ..
Rick
49

Das einzige, worauf Sie achten müssen, ist, dass DECIMAL (19,4) und DECIMAL (19,4) unterschiedliche Bedeutungen haben, wenn Sie von einer Datenbank in eine andere migrieren

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

    DBASE: 10,5 (10 Ganzzahlen, 5 Dezimalstellen)
    MYSQL: 15,5 (15 Stellen, 10 Ganzzahlen (15-5), 5 Dezimalstellen)
SeanJA
quelle
Link ist jetzt leider tot.
Marco Aurélio Deleu
1
@ MarcoAurélioDeleu - Ich habe den Link so geändert, dass er auf die Seite auf der Wayback-Maschine verweist, sodass Sie sie im Jahr 2009 sehen können.
Tony
17

Es ist auch wichtig herauszufinden, wie viele Dezimalstellen möglicherweise für Ihre Berechnungen erforderlich sind.

Ich habe an einem Aktienkursantrag gearbeitet, bei dem der Preis von einer Million Aktien berechnet werden musste. Der notierte Aktienkurs musste mit einer Genauigkeit von 7 Stellen gespeichert werden.

Leah
quelle
7
Es ist ein guter Punkt - besonders in Finanz-Apps bedeutet "Preis" mit Sicherheit nicht "Geld"
Mike Woodhouse
17

Assafs Antwort von

Kommt darauf an, wie viel Geld du hast ...

klingt flippig, ist aber eigentlich relevant.

Erst heute hatten wir ein Problem, bei dem ein Datensatz nicht in unsere Rate-Tabelle eingefügt werden konnte, weil eine der Spalten (Bruttorate) auf Dezimal (11,4) gesetzt ist und unsere Produktabteilung gerade einen Vertrag für Zimmer in einem erstaunlichen Resort erhalten hat in Bora Bora, die für mehrere Millionen pazifische Franken pro Nacht verkauft werden ... etwas, das bei der Entwicklung des Datenbankschemas vor 10 Jahren nie erwartet wurde.

Scott Ferguson
quelle
2
Aus diesem Grund habe ich eine Dezimalzahl (19,4) empfohlen. Klingt vielleicht nach Overkill, aber Sie wissen nie, wann Sie eine wirklich große Menge in diesem Feld speichern müssen.
Kibbee
2
@Kibbee: Ich hätte dir bis heute nicht zugestimmt, was unsere Anforderungen angeht. (Für 6 Jahre (11,4) war vollkommen in Ordnung ...)
Scott Ferguson
@ Kibbee Das klingt wie 640 Kb Meme :)
Nikita Bosik
13

Bei Buchhaltungsanwendungen werden die Werte häufig als Ganzzahlen gespeichert (einige sagen sogar, dass dies der einzige Weg ist). Um sich ein Bild zu machen, nehmen Sie den Betrag der Transaktionen (nehmen wir 100,23 USD an) und multiplizieren Sie ihn mit 100, 1000, 10000 usw., um die erforderliche Genauigkeit zu erhalten. Wenn Sie also nur Cent speichern müssen und sicher auf- oder abrunden können, multiplizieren Sie einfach mit 100. In meinem Beispiel würde dies 10023 als zu speichernde Ganzzahl ergeben. Sie sparen Platz in der Datenbank und das Vergleichen von zwei Ganzzahlen ist viel einfacher als das Vergleichen von zwei Floats. Meine $ 0,02.

Däne Bendixen
quelle
Wie lagern Sie 6.125 (6 1/8)?
PeterToTheThird
Ich denke, er würde es als ganze Zahl 6125 speichern.
Jimmy Knoot
2
Wie wäre das besser als DECIMAL? Sie müssen sehr vorsichtig sein, wenn Sie Pennys, Mühlen oder Millrays immer zu den richtigen Zeiten in Dollar umrechnen.
Ich habe gelesen, dass die Leistung mit INT normalerweise schneller ist als mit DECIMAL, selbst in den neuesten Versionen von MySQL. Es ist auch einfacher, wenn Sie diese Werte in PHP oder etwas anderes bringen und Werte vergleichen müssen.
Dane Bendixen
9

Super später Einstieg, aber GAAP ist eine gute Faustregel.

Wenn Ihre Anwendung Geldwerte bis zu einer Billion verarbeiten muss, sollte dies funktionieren: 13,2 Wenn Sie GAAP (General Accepted Accounting Principles) einhalten müssen, verwenden Sie: 13,4

Normalerweise sollten Sie Ihre Geldwerte bei 13,4 summieren, bevor Sie die Ausgabe auf 13,2 runden.

Quelle: Bester Datentyp zum Speichern des Geldwerts in MySQL

Damian
quelle
5

Sie könnten so etwas wie DECIMAL(19,2)Standard für alle Ihre Geldwerte verwenden, aber wenn Sie immer nur Werte unter 1.000 US-Dollar speichern, wird dies nur eine Verschwendung von wertvollem Datenbankspeicher sein.

Für die meisten Implementierungen DECIMAL(N,2)wäre dies ausreichend, wenn der Wert von Nmindestens die Anzahl der Stellen vor .der größten Summe ist, die Sie jemals in diesem Feld gespeichert haben + 5. Wenn Sie also nie erwarten, Werte über 999999,99 zu speichern, DECIMAL(11,2)sollte dies mehr als ausreichend sein (bis sich die Erwartungen ändern).

Wenn Sie GAAP- konform sein möchten, können Sie wählenDECIMAL(N,4) , wobei der Wert von Nmindestens die Anzahl der Stellen vor .der größten Summe ist, die Sie jemals in diesem Feld gespeichert haben + 7.

John Slegers
quelle
3

Dies hängt von der Art der Daten ab. Sie müssen es vorher betrachten.

Mein Fall

  • Dezimalzahl (13,4) ohne Vorzeichen für die Aufzeichnung von Geldtransaktionen
    • Speichereffizient (ohnehin 4 Bytes für jede Seite des Dezimalpunkts) 1
    • GAAP-konform
  • Dezimalzahl (19,4) ohne Vorzeichen für Aggregate
    • Wir brauchen mehr Platz für mehrere Transaktionen im Wert von mehreren Milliarden
    • Die Halbkonformität mit dem Datentyp MS Currency schadet nicht 2
    • Pro Datensatz wird mehr Speicherplatz benötigt (11 Byte - 7 links und 4 rechts). Dies ist jedoch in Ordnung, da weniger Datensätze für Aggregate 1 vorhanden sind
  • Dezimalzahl (10,5) für Wechselkurse
    • Sie werden normalerweise mit insgesamt 5 Ziffern angegeben, sodass Sie Werte wie 1.2345 und 12.345 finden können, jedoch nicht 12345.67890
    • Es ist eine weit verbreitete Konvention, aber kein kodifizierter Standard (zumindest nach meinem Wissen über die schnelle Suche).
    • Sie könnten es mit demselben Speicher dezimal (18,9) machen, aber die Datentypeinschränkungen sind ein wertvoller integrierter Validierungsmechanismus

Warum (M, 4)?

  • Es gibt Währungen, die sich in tausend Cent aufteilen
  • Es gibt Geldäquivalente wie "Unidad de Fermento", "CLF", ausgedrückt mit 4 signifikanten Dezimalstellen 3 , 4
  • Es ist GAAP-konform

Abtausch

  • geringere Präzision:
    • weniger Lagerkosten
    • schnellere Berechnungen
    • geringeres Rechenfehlerrisiko
    • schnellere Sicherung und Wiederherstellung
  • höhere Präzision:
    • zukünftige Kompatibilität (Zahlen steigen tendenziell)
    • Zeitersparnis bei der Entwicklung (Sie müssen kein halbes System neu erstellen, wenn die Grenzwerte erreicht sind)
    • Geringeres Risiko eines Produktionsausfalls aufgrund unzureichender Lagergenauigkeit

Kompatibles Extrem

Obwohl Sie in MySQL Dezimalstellen (65,30) verwenden können, scheinen 31 für die Skalierung und 30 für die Genauigkeit unsere Grenzen zu sein, wenn wir die Übertragungsoption offen lassen möchten.

Maximale Skalierung und Präzision in den meisten gängigen RDBMS:

            Präzisionswaage
Oracle 31 31
T-SQL 38 38
MySQL 65 30
PostgreSQL 131072 16383

6 , 7 , 8 , 9

Angemessenes Extrem

  1. Warum (27,4)?
    • Sie wissen nie, wann das System simbabwische Dollar speichern muss

September 2015 Die simbabwische Regierung gab bekannt, dass sie simbabwische Dollar in US-Dollar mit einem Kurs von 1 USD bis 35 Billiarden simbabwischen Dollar 5 umtauschen werde

Wir neigen dazu zu sagen "Ja, sicher ... ich werde diese verrückten Figuren nicht brauchen". Nun, Simbabwer sagten das auch. Vor nicht allzu langer Zeit.

Stellen Sie sich vor, Sie müssen eine Transaktion von 1 Mio. USD in simbabwischen Dollar erfassen (heute vielleicht unwahrscheinlich, aber wer weiß, wie dies in 10 Jahren aussehen wird?).

  1. (1 Mio. USD) * (35 Quadrylion ZWL) = (10 ^ 6) * (35 * 10 ^ 15) = 35 * 10 ^ 21
  2. wir brauchen:
    • 2 Ziffern zum Speichern von "35"
    • 21 Ziffern zum Speichern der Nullen
    • 4 Stellen rechts vom Dezimalpunkt
  3. Dies ergibt eine Dezimalzahl (27,4), die uns 15 Bytes für jeden Eintrag kostet
  4. Wir können ohne Kosten eine weitere Ziffer links hinzufügen - wir haben eine Dezimalstelle (28,4) für 15 Bytes
  5. Jetzt können wir 10 Mio. USD-Transaktionen in simbabwischen Dollar speichern oder uns vor einem weiteren Hiperinflations-Streik schützen, der hoffentlich nicht stattfinden wird
kshishkin
quelle
0

Das mag zwar spät sein, aber es wird jemand anderem helfen. Aufgrund meiner Erfahrung und Forschung habe ich Dezimalstellen (19, 6) kennengelernt und akzeptiert. Das ist, wenn ich mit PHP und MySQL arbeite. bei der Arbeit mit viel Geld und Wechselkurs

wertvoll
quelle