Ich schreibe ein Java-Programm, das Währungsaustauschdaten mischt. Die Daten können mehrere Dezimalziffern wie "0.973047" haben. Nach einigen Recherchen konnte ich herausfinden, dass BigDecimal der richtige Datentyp für Java ist, aber welchen Datentyp sollte ich für PostgreSQL verwenden?
NUMERIC
/ DECIMAL
NUMERIC
/%Co_de% , als beliebiger Präzisionstyp.
Zwei wichtige Punkte zu DECIMAL
/ NUMERIC
:
DECIMAL
& amp; NUMERIC
sind nahe, aber nicht identisch gemäß dem SQL-Standard. In SQL: 92 wird die angegebene Genauigkeit für DECIMAL
berücksichtigt, für NUMERIC
hingegen der Datenbankserver erlaubt eine zusätzliche Genauigkeit, die über das hinausgeht, was Sie angegeben haben. Auch hier weicht Postgres etwas vom Standard ab, wobei sowohl DECIMAL
& amp; NUMERIC
dokumentiert als gleichwertig. Begriffe:
Machen Sie sich mit den Spezifikationen Ihres Projekts für Präzision und Skalierung vertraut:
DECIMAL
type Postgres bietet auch einen MONEY
-Typ an. Das klingt vielleicht richtig, aber wahrscheinlich nicht gut für die meisten Zwecke. Ein Nachteil ist, dass mit MONEY
die Skalierung durch eine datenbankweite Konfigurationseinstellung basierend auf Gebietsschema . Diese Einstellung kann sich gefährlich ändern, wenn Sie den Server wechseln oder andere Änderungen vornehmen. Darüber hinaus können Sie diese Einstellung für bestimmte Spalten nicht steuern, während Sie die Skalierung für jede Spalte von MONEY
type festlegen können. Schließlich ist NUMERIC
kein Standard-SQL, wie in dieser Liste der SQL-Standarddatentypen MONEY
Eine andere Alternative, die von einigen verwendet wird, ist das Verschieben des Dezimalpunkts und das Speichern im großen Integer-Datentyp.
Wenn Sie zum Beispiel USD Dollars für den Penny speichern, multiplizieren Sie jede beliebige Anzahl von Dezimalstellen mit 100, umgerechnet auf eine ganze Zahl Geben Sie ein und fahren Sie fort. Zum Beispiel wird $ 123.45 zur Ganzzahl 12.345.
Der Vorteil dieses Ansatzes ist eine schnellere Ausführung. Operationen wie MONEY
sind sehr schnell, wenn sie in Ganzzahlen ausgeführt werden. Ein weiterer Vorteil von Ganzzahlen ist die geringere Speichernutzung.
Ich finde diesen Ansatz lästig, verwirrend und riskant. Ärgerlich, weil Computer für uns arbeiten sollten, nicht gegen uns. Riskant, weil ein Programmierer oder Benutzer es unterlassen kann, Multiplikationen / Divisionen zu verwenden, um zurück in die Bruchzahl zu konvertieren, was zu falschen Ergebnissen führt. Wenn Sie in einem System ohne gute Unterstützung für genaue Bruchzahlen arbeiten, ist dieser Ansatz möglicherweise eine akzeptable Problemumgehung.
Ich sehe keinen Vorteil darin, den Dezimalpunkt zu verschieben, wenn wir sum
/ DECIMAL
in SQL und NUMERIC
in Java.
Bei der Programmierung Ihrer App sowie bei allen Berechnungen, die auf der Server-Seite von Postgres durchgeführt werden, sollten Sie sehr vorsichtig und rundlich und verkürzt im Dezimalbruch beachten. Und teste nach unbeabsichtigten NaNs , die auftauchen.
Bei beiden Seiten, App und Postgres, vermeiden Sie immer Fließkomma Datentypen für Geldarbeit. Gleitkommazahl ist für Leistungsgeschwindigkeit ausgelegt, aber für die Genauigkeit . Berechnungen können zu scheinbar verrückten zusätzlichen Ziffern im Dezimalbruch führen. Nicht gut für finanzielle / finanzielle oder andere Zwecke, wo Genauigkeit wichtig ist.
BigDecimal
Ja, in Java möchten Sie NaN
als Ihr beliebiger Präzisionstyp. BigDecimal
ist langsamer und benötigt mehr Speicher, speichert aber genau Ihre Geldbeträge. SQL BigDecimal
/ BigDecimal
sollte wie besprochen auf NUMERIC
abgebildet werden hier und auf StackOverflow .
DECIMAL
ist eines der besten Dinge über Java. Ich kenne keine andere Plattform mit einer ähnlichen Klasse, vor allem eine, die so gut implementiert und gut durchdacht ist, mit wichtigen Verbesserungen und Korrekturen, die im Laufe der Jahre gemacht wurden.
Die Verwendung von BigDecimal
ist definitiv langsamer als die Java-Gleitkommatypen . BigDecimal
& amp; %Code%. Aber in realen Apps bezweifle ich, dass Ihre Geldberechnungen einen Engpass darstellen. Und außerdem, was wollen Sie oder Ihre Kunden: die schnellsten Geldberechnungen oder genauen Geldberechnungen?
Um eine möglichst gute (und genaue) Genauigkeit zu erhalten, können Sie NUMERIC
DECIMAL
), das eine hohe Genauigkeit hat und Ihnen erlaubt, die benötigte Genauigkeit zu bestimmen;
ZAHLEN
Benutzerdefinierte Genauigkeit, genau bis zu 131072 Stellen vor dem Komma; bis zu 16383 Nachkommastellen
Im Allgemeinen sollte Geld nicht als Fließkomma gespeichert werden. Der beste Ansatz besteht normalerweise darin, den Geldbetrag als eine Ganzzahl der kleinsten zulässigen Größe (beispielsweise einen US-Cent) zu speichern und für die Eingabe und Anzeige zu formatieren. Dies ist im Wesentlichen eine Spalte DECIMAL
mit fester Genauigkeit in SQL, aber wenn Sie sie zurück in Java übertragen, laufen Sie immer noch Gefahr, die Genauigkeit zu verlieren (z. B. was passiert, wenn Sie genau die Hälfte der letzten zulässigen Zahl teilen)?
Tags und Links sql java postgresql jdbc currency