Ich bin gespannt, ob es einen echten Unterschied zwischen dem money
Datentyp und so etwas gibt decimal(19,4)
(was Geld intern verwendet, glaube ich).
Mir ist bekannt, dass dies money
spezifisch für SQL Server ist. Ich möchte wissen, ob es einen zwingenden Grund gibt, einen über den anderen zu wählen. Die meisten SQL Server-Beispiele (z. B. die AdventureWorks-Datenbank) verwenden money
und nicht decimal
für Dinge wie Preisinformationen.
Sollte ich den Gelddatentyp einfach weiter verwenden, oder hat die Verwendung von Dezimalzahlen einen Vorteil? Geld besteht aus weniger Zeichen, aber das ist kein gültiger Grund :)
sql-server
types
Wayne Molina
quelle
quelle
DECIMAL(19, 4)
Dies ist eine beliebte Wahl. Überprüfen Sie dies auch hier. Weltwährungsformate, um zu entscheiden, wie viele Dezimalstellen verwendet werden sollen. Hoffnung hilft.Antworten:
Niemals sollten Sie Geld verwenden. Es ist nicht genau und es ist reiner Müll; Verwenden Sie immer dezimal / numerisch.
Führen Sie dies aus, um zu sehen, was ich meine:
Ausgabe: 2949.0000 2949.8525
Zu einigen Leuten, die sagten, dass Sie Geld nicht durch Geld teilen:
Hier ist eine meiner Fragen zur Berechnung von Korrelationen, und die Änderung in Geld führt zu falschen Ergebnissen.
quelle
money
Overmoney
beiseite, diese "Illustration" ist manipulativ. Es ist eine dokumentierte Tatsache,money
die eine feste und sehr begrenzte Genauigkeit hat. In solchen Fällen sollte man zuerst multiplizieren und dann dividieren. Wenn Sie in diesem Beispiel die Reihenfolge der Operatoren ändern, erhalten Sie identische Ergebnisse. A ist immoney
Wesentlichen ein 64-Bit-Int, und wenn Sie sich mit Ints befassen würden, würden Sie vor dem Teilen multiplizieren.SQLMenace sagte, Geld sei ungenau. Aber Sie multiplizieren / teilen Geld nicht durch Geld! Wie viel kostet 3 Dollar mal 50 Cent? 150 Dollar? Sie multiplizieren / dividieren Geld durch Skalare, die dezimal sein sollten.
Ergebnisse im richtigen Ergebnis:
money
ist gut, solange Sie nicht mehr als 4 Dezimalstellen benötigen und sicherstellen, dass Ihre Skalare - die kein Geld darstellen -decimal
s sind.quelle
money / money
? Die Antwort sind ganze Einheiten ohne Dollarzeichen, was richtig ist! Dies ist ein durchaus vernünftiges Szenario, das darauf hindeutet, dass aufgrund seltsamer Randfälle wie diesermoney
kein guter Datentyp zu verwenden ist, da das Ergebnis immer wieder abgeschnitten wird, um zu passen,money
anstatt den normalen Regeln für Präzision und Skalierung zu folgen. Was ist, wenn Sie die Standardabweichung einer Reihe vonmoney
Werten berechnen möchten ? Ja,Sqrt(Sum(money * money))
(vereinfacht) macht tatsächlich Sinn.Alles ist gefährlich, wenn Sie nicht wissen, was Sie tun
Selbst hochpräzise Dezimaltypen können den Tag nicht retten:
1.000000 <- Sollte 0.6000000 sein
Die
money
Typen sind ganze ZahlenDie Textdarstellungen von
smallmoney
unddecimal(10,4)
mögen gleich aussehen, aber das macht sie nicht austauschbar. Erschrecken Sie, wenn Sie Daten als gespeichert sehenvarchar(10)
? Das ist das gleiche.Hinter den Kulissen sind
money
/smallmoney
nur einbigint
/int
Der Dezimalpunkt in der Textdarstellung vonmoney
ist visueller Flaum, genau wie die Bindestriche in einem JJJJ-MM-TT-Datum. SQL speichert diese nicht intern.Wählen Sie in Bezug auf
decimal
vsmoney
, was für Ihre Bedürfnisse geeignet ist. Diemoney
Typen existieren, weil das Speichern von Abrechnungswerten als ganzzahlige Vielfache von 1/10000 der Einheit sehr häufig ist. Wenn Sie mit tatsächlichem Geld und Berechnungen zu tun haben, die über das einfache Addieren und Subtrahieren hinausgehen, sollten Sie dies nicht auf Datenbankebene tun! Führen Sie dies auf Anwendungsebene mit einer Bibliothek durch, die Banker's Rounding (IEEE 754) unterstützt.quelle
Mir ist klar, dass WayneM erklärt hat, dass er weiß, dass Geld spezifisch für SQL Server ist. Er fragt jedoch, ob es Gründe gibt, Geld über Dezimalzahl zu verwenden oder umgekehrt, und ich denke, ein offensichtlicher Grund sollte noch angegeben werden, und die Verwendung von Dezimalzahl bedeutet, dass Sie sich weniger Sorgen machen müssen, wenn Sie jemals Ihr DBMS ändern müssen - was passieren kann.
Machen Sie Ihre Systeme so flexibel wie möglich!
quelle
date
Typ, würde ich sagen, dass Sie immer solche Probleme haben werden. Sie sollten sagen "Verwenden Sie keine veralteten Typen, wenn die Datenbank bereits bessere, standardkonformere Typen bereitstellt und vor den veralteten Typen warnt ".Nun, ich mag
MONEY
! Es ist ein Byte billiger alsDECIMAL
und die Berechnungen werden schneller ausgeführt, da Additions- und Subtraktionsoperationen (unter dem Deckmantel) im Wesentlichen ganzzahlige Operationen sind. Das Beispiel von @ SQLMenace - eine großartige Warnung fürINT
Unbewusste - könnte auch auf Eger angewendet werden, bei denen das Ergebnis Null wäre. Dies ist jedoch kein Grund, gegebenenfalls keine Ganzzahlen zu verwenden .Es ist also absolut "sicher" und angemessen zu verwenden,
MONEY
wenn es sich um das handelt, womit Sie es zu tun haben,MONEY
und es gemäß den folgenden mathematischen Regeln zu verwenden (wie beiINT
eger).Wäre es besser gewesen, wenn SQL Server die Division und Multiplikation von
MONEY
's inDECIMAL
s (oderFLOAT
s?) Gefördert hätte - möglicherweise, aber sie haben sich nicht dafür entschieden; Sie haben sich auch nicht dafür entschieden,INT
Eger zuFLOAT
s zu befördern, wenn sie sie teilen.MONEY
hat kein Präzisionsproblem; DassDECIMAL
ein größerer Zwischentyp bei Berechnungen verwendet wird, ist nur ein "Merkmal" der Verwendung dieses Typs (und ich bin mir nicht sicher, wie weit sich dieses "Merkmal" erstreckt).Um die spezifische Frage zu beantworten, ein "zwingender Grund"? Nun, wenn Sie in eine absolute Höchstleistung wollen ,
SUM(x)
wox
könnte entwederDECIMAL
oderMONEY
, dannMONEY
wird die Nase vorn haben.Vergessen Sie auch nicht, dass es ein kleinerer Cousin ist -
SMALLMONEY
nur 4 Bytes, aber es ist maximal214,748.3647
- was für Geld ziemlich klein ist - und daher oft nicht gut passt.Wenn Sie das Intermediate explizit einer Variablen zuweisen, tritt
DECIMAL
das gleiche Problem auf, um die Verwendung größerer Zwischentypen zu beweisen :Produziert
2950.0000
(okay, also zumindestDECIMAL
gerundet anstattMONEY
abgeschnitten - genau wie eine ganze Zahl.)quelle
MONEY
ist ein Byte kleiner als ein großesDECIMAL
, mit bis zu 19 Stellen Genauigkeit. Die meisten realen Geldberechnungen (bis zu 9,99 Mio. USD) können jedoch in a passenDECIMAL(9, 2)
, was nur fünf Bytes erfordert. Sie können Größe sparen, sich weniger um Rundungsfehler kümmern und Ihren Code portabler machen.Wir sind gerade auf ein sehr ähnliches Problem gestoßen, und ich bin jetzt ein +1, weil ich Geld nur in Präsentationen auf oberster Ebene verwendet habe. Wir haben mehrere Tabellen (effektiv einen Verkaufsgutschein und eine Verkaufsrechnung), von denen jede aus historischen Gründen ein oder mehrere Geldfelder enthält, und wir müssen eine anteilige Berechnung durchführen, um herauszufinden, wie viel von der gesamten Rechnungssteuer für jede relevant ist Zeile auf dem Verkaufsgutschein. Unsere Berechnung ist
Dies führt zu einer realen Geld / Geld-Berechnung, die Skalierungsfehler im Teilungsteil verursacht, die sich dann zu einem falschen Mehrwertsteuerverhältnis multiplizieren. Wenn diese Werte anschließend addiert werden, erhalten wir eine Summe der Mehrwertsteueranteile, die sich nicht zum Gesamtrechnungswert addieren. Wäre einer der Werte in den Klammern eine Dezimalzahl gewesen (ich werde einen davon als solchen umwandeln), wäre der Mehrwertsteueranteil korrekt.
Wenn die Klammern ursprünglich nicht da waren, funktionierte dies früher, ich denke, aufgrund der größeren Werte simulierte es effektiv eine höhere Skala. Wir haben die Klammern hinzugefügt, weil zuerst die Multiplikation durchgeführt wurde, was in einigen seltenen Fällen die für die Berechnung verfügbare Genauigkeit beeinträchtigte, aber dies hat jetzt diesen viel häufigeren Fehler verursacht.
quelle
Als Gegenpol zur allgemeinen Ausrichtung der anderen Antworten. Sehen Sie die vielen Vorteile von Geld… Datentyp! im SQLCAT-Handbuch zur relationalen Engine
Insbesondere möchte ich auf Folgendes hinweisen
Die Antwort auf die Frage lautet also "es kommt darauf an". Sie müssen bei bestimmten arithmetischen Operationen vorsichtiger sein, um die Präzision zu erhalten. Möglicherweise ist dies jedoch aufgrund von Leistungsaspekten sinnvoll.
quelle
Ich möchte eine andere Sicht auf GELD vs. NUMERISCH geben, die größtenteils auf meinem eigenen Fachwissen und meiner Erfahrung beruht ... Mein Standpunkt hier ist GELD, weil ich lange Zeit damit gearbeitet habe und NUMERISCH nie wirklich viel benutzt habe. .
GELD Pro:
Native Datentyp . Es verwendet einen nativen Datentyp ( Ganzzahl ) wie ein CPU-Register (32 oder 64 Bit), sodass für die Berechnung kein unnötiger Overhead erforderlich ist, sodass sie kleiner und schneller ist . GELD benötigt 8 Byte und NUMERICAL (19, 4) ) benötigt 9 Bytes (12,5% größer) ...
GELD ist schneller, solange es verwendet wird (als Geld). Wie schnell? Mein einfacher
SUM
Test mit 1 Million Daten zeigt, dass GELD 275 ms und NUMERIC 517 ms beträgt ... Das ist fast doppelt so schnell ... Warum SUM-Test? Siehe nächster Pro- PunktGELD Con:
money
muss es nicht so präzise sein und soll als Geld verwendet werden, nicht nur als a Nummer...Aber ... Groß, aber hier ist sogar Ihre Anwendung mit echtem Geld verbunden, aber verwenden Sie sie nicht in vielen SUM-Operationen, wie in der Buchhaltung. Wenn Sie stattdessen viele Divisionen und Multiplikationen verwenden, sollten Sie kein GELD verwenden ...
quelle
money
Spalte speichernAlle vorherigen Beiträge bringen gültige Punkte, aber einige beantworten die Frage nicht genau.
Die Frage ist: Warum sollte jemand Geld bevorzugen, wenn wir bereits wissen, dass es sich um einen weniger genauen Datentyp handelt, der bei komplexen Berechnungen Fehler verursachen kann?
Sie verwenden Geld, wenn Sie keine komplexen Berechnungen durchführen und diese Präzision gegen andere Anforderungen eintauschen können.
Zum Beispiel, wenn Sie diese Berechnungen nicht durchführen müssen und Daten aus gültigen Währungstextzeichenfolgen importieren müssen. Diese automatische Konvertierung funktioniert nur mit dem Datentyp MONEY:
Ich weiß, dass Sie Ihre eigene Importroutine erstellen können. Manchmal möchten Sie jedoch keine Importroutine mit weltweit spezifischen Gebietsschemaformaten neu erstellen.
Ein weiteres Beispiel, wenn Sie diese Berechnungen nicht durchführen müssen (Sie müssen nur einen Wert speichern) und 1 Byte sparen müssen (Geld benötigt 8 Byte und Dezimalzahl (19,4) 9 Byte). In einigen Anwendungen (schnelle CPU, großer Arbeitsspeicher, langsame E / A), wie z. B. das Lesen großer Datenmengen, kann dies auch schneller sein.
quelle
Sie sollten kein Geld verwenden, wenn Sie Multiplikationen / Divisionen für den Wert durchführen müssen. Geld wird auf die gleiche Weise gespeichert wie eine Ganzzahl, während Dezimalstellen als Dezimalpunkt und Dezimalstellen gespeichert werden. Dies bedeutet, dass das Geld in den meisten Fällen an Genauigkeit verliert, während die Dezimalzahl dies nur tut, wenn sie wieder auf die ursprüngliche Skala zurückgesetzt wird. Geld ist ein Fixpunkt, daher ändert sich seine Skala während der Berechnungen nicht. Da es sich jedoch um einen festen Punkt handelt, wenn er als Dezimalzeichenfolge gedruckt wird (im Gegensatz zu einer festen Position in einer Zeichenfolge der Basis 2), werden Werte bis zur Skala von 4 genau dargestellt. Für Addition und Subtraktion ist Geld also in Ordnung.
Eine Dezimalstelle wird intern in der Basis 10 dargestellt, und daher basiert die Position des Dezimalpunkts auch auf der Basis 10-Zahl. Wodurch sein Bruchteil seinen Wert genau darstellt, genau wie bei Geld. Der Unterschied besteht darin, dass Zwischenwerte der Dezimalzahl eine Genauigkeit von bis zu 38 Stellen beibehalten können.
Bei einer Gleitkommazahl wird der Wert binär wie eine Ganzzahl gespeichert, und die Position des Dezimalpunkts (oder Binärpunkts) ist relativ zu den Bits, die die Zahl darstellen. Da es sich um einen binären Dezimalpunkt handelt, verlieren Basis-10-Zahlen direkt nach dem Dezimalpunkt an Genauigkeit. 1/5 oder 0,2 kann auf diese Weise nicht genau dargestellt werden. Weder Geld noch Dezimalstellen leiden unter dieser Einschränkung.
Es ist einfach genug, Geld in Dezimalzahlen umzuwandeln, die Berechnungen durchzuführen und den resultierenden Wert dann wieder in einem Geldfeld oder einer Geldvariablen zu speichern.
Von meinem POV möchte ich, dass Dinge, die mit Zahlen passieren, einfach passieren, ohne dass ich zu viel darüber nachdenken muss. Wenn alle Berechnungen in Dezimalzahlen konvertiert werden sollen, möchte ich für mich nur Dezimalzahlen verwenden. Ich würde das Geldfeld für Anzeigezwecke speichern.
In Bezug auf die Größe sehe ich nicht genug Unterschiede, um meine Meinung zu ändern. Geld benötigt 4 - 8 Bytes, während Dezimal 5, 9, 13 und 17 sein kann. Die 9 Bytes können den gesamten Bereich abdecken, den die 8 Bytes Geld können. Indexweise (Vergleichen und Suchen sollten vergleichbar sein).
quelle
Ich habe einen Grund gefunden, Dezimal über Geld in Bezug auf Genauigkeit zu verwenden.
DecimalResult> 1.000000
MoneyResult> 0,9999
FloatResult> 1
Testen Sie es einfach und treffen Sie Ihre Entscheidung.
quelle
Ich habe gerade diesen Blogeintrag gesehen: Money vs. Decimal in SQL Server .
Was im Grunde sagt, dass Geld ein Präzisionsproblem hat ...
Für den
money
Typ erhalten Sie 19.30 statt 19.34. Ich bin nicht sicher, ob es ein Anwendungsszenario gibt, das Geld zur Berechnung in 1000 Teile aufteilt, aber dieses Beispiel weist einige Einschränkungen auf.quelle
money
undsmallmoney
sind auf ein Zehntausendstel der von ihnen repräsentierten Währungseinheiten genau.» wie gesagt in msdn.microsoft.com/en-us/library/ms179882.aspx weiß jeder, der "es ist Müll" sagt, nicht, wovon er spricht.