Unterschied zwischen numerisch, float und dezimal in SQL Server

322

Was sind die Unterschiede zwischen numeric, floatund decimalDatentypen und die in welchen Situationen verwendet werden soll?

Welche Art von Finanztransaktion (z. B. für Gehaltsbereiche) wird bevorzugt und warum?

priyanka.sarkar
quelle
1
Der obige dezimale und numerische Link muss auf docs.microsoft.com/en-us/sql/t-sql/data-types/… aktualisiert werden . Der obige Link existiert nicht mehr.
Nigel Ainscoe
1
Wenn Sie sich mit Finanzthemen befassen, ist es normalerweise interessant, mit Ganzzahltypen zu arbeiten , abgesehen von Gleitkomma- Typen, und die Werte als Cent anstelle von beispielsweise Dollar zu speichern .
Pedro

Antworten:

493

Verwenden Sie den Float- oder Real -Datentyp nur, wenn die Genauigkeit der Dezimalzahl (bis zu 38 Stellen) nicht ausreicht

  • Ungefähre numerische Datentypen speichern nicht die genauen Werte, die für viele Zahlen angegeben wurden. Sie speichern eine extrem enge Annäherung an den Wert. ( Technet )

  • Vermeiden Sie die Verwendung von Float- oder Real-Spalten in den Suchbedingungen der WHERE-Klausel, insbesondere der Operatoren = und <> ( Technet ).

Daher ist die Genauigkeit der Dezimalzahl im Allgemeinen [10E38 ~ 38 Stellen], wenn Ihre Zahl hineinpasst, und der kleinere Speicherplatz (und möglicherweise die Geschwindigkeit) von Float ist nicht wichtig, und der Umgang mit abnormalen Verhaltensweisen und Problemen mit ungefähren numerischen Typen ist dies nicht akzeptabel, verwenden Sie Dezimal im Allgemeinen .

weitere nützliche Informationen

  • numerisch = dezimal (5 bis 17 Byte) ( exakter numerischer Datentyp)
    • wird in .NET auf Decimal abgebildet
    • Beide haben (18, 0) als Standardparameter (Genauigkeit, Skalierung) in SQL Server
    • scale = maximale Anzahl von Dezimalstellen, die rechts vom Dezimalpunkt gespeichert werden können.
    • Bitte beachten Sie, dass Geld (8 Byte) und Smallmoney (4 Byte) ebenfalls exakt sind und in .NET der Dezimalzahl zugeordnet sind und 4 Dezimalstellen ( MSDN ) haben.
    • dezimal und numerisch (Transact-SQL) - MSDN
  • real (4 Byte) ( ungefährer numerischer Datentyp)
  • float (8 Byte) ( Ungefährer numerischer Datentyp)
    • wird Double in .NET zugeordnet
  • Alle exakten numerischen Typen führen immer zum gleichen Ergebnis, unabhängig davon, welche Art von Prozessorarchitektur verwendet wird oder wie groß die Zahlen sind
  • Der dem Float-Datentyp bereitgestellte Parameter definiert die Anzahl der Bits, die zum Speichern der Mantisse der Gleitkommazahl verwendet werden .
  • Der ungefähre numerische Datentyp benötigt normalerweise weniger Speicher und hat eine bessere Geschwindigkeit (bis zu 20x). Sie sollten auch berücksichtigen, wann sie in .NET konvertiert wurden

Genaue numerische Datentypen Ungefähre numerische Datentypen

Hauptquelle : MCTS Self-Paced Training Kit (Prüfung 70-433): Microsoft® SQL Server® 2008-Datenbankentwicklung - Kapitel 3 - Tabellen, Datentypen und deklarative Datenintegrität Lektion 1 - Auswählen von Datentypen (Richtlinien) - Seite 93

Iman
quelle
17
use the float or real data types only if the precision provided by decimal is insufficient- Ich dachte, real ist WENIGER genau als dezimal. Wie kommt es, dass Sie schreiben, um real zu verwenden, wenn die Dezimalzahl nicht ausreicht?
BornToCode
7
real ist weniger genau und wird daher nur empfohlen, wenn große Zahlen gespeichert werden, die größer als die Dezimalzahl (> 10e38) sind, oder wenn Platzüberlegungen erforderlich sind. Ich denke, die Genauigkeit hier im Zitat bedeutet mögliche Werte und Größen, nicht die Genauigkeit
Iman
11
@BornToCode Die "Genauigkeit" bezieht sich hier darauf, wie breit die Werte sind, die Sie speichern möchten. Wenn Sie Werte zwischen 1e10 und 1e-10 speichern müssen, ist decimaldies in Ordnung. Das ist eine Genauigkeit von 20. Wenn Sie Werte zwischen beispielsweise 1e20 und 1e-20 speichern müssen, decimal können Sie das nicht . Das sind 40 Stellen Genauigkeit. Sie können 1e20 und 1e-20 niemals im selben decimalFeld speichern . Stattdessen können Sie verwenden float, das intern alles als Protokoll der Basis 2 speichert. Dies ermöglicht den vollen Genauigkeitsbereich in einem Feld mit dem Nachteil, dass nur die ersten ~ 8 Ziffern genau sind.
Bacon Bits
Ich dritte BornToCode und Iman Kommentare. Ich habe gerade experimentiert (mit SQL Server 2012), und es scheint, dass das Maschinen-Epsilon für float (53), den Gleitkommatyp mit der höchsten Genauigkeit, 2.22044604925031E-16 ist. Sie würden also ungefähr 15 signifikante Zahlen daraus erhalten. Auf der anderen Seite kann ich 38 signifikante Ziffern erhalten.
Stewart
"Verwenden Sie die float..." - sagte wer? Ist das ein Zitat oder deine Meinung?
user443854
24

Richtlinien von MSDN: Verwenden von Dezimal-, Gleitkomma- und Realdaten

Die maximale Standardgenauigkeit von numerischen und dezimalen Datentypen beträgt 38. In Transact-SQL entspricht numerisch dem dezimalen Datentyp. Verwenden Sie den Dezimaldatentyp, um Zahlen mit Dezimalstellen zu speichern, wenn die Datenwerte genau wie angegeben gespeichert werden müssen.

Das Verhalten von float und real folgt der IEEE 754-Spezifikation für ungefähre numerische Datentypen. Verwenden Sie diese Datentypen aufgrund der ungefähren Natur des Float- und des Real-Datentyps nicht, wenn ein genaues numerisches Verhalten erforderlich ist, z. B. bei Finanzanwendungen, bei Operationen mit Rundung oder bei Gleichheitsprüfungen. Verwenden Sie stattdessen die Datentypen Integer, Decimal, Money oder Smallmoney. Vermeiden Sie die Verwendung von Float- oder Real-Spalten in den Suchbedingungen der WHERE-Klausel, insbesondere der Operatoren = und <>. Es ist am besten, Float- und Real-Spalten auf> oder <Vergleiche zu beschränken.

kmote
quelle
Die (feste) Anzahl von Dezimalstellen wird in der ScaleSpalte angegeben.
Cees Timmerman
1
Wenn Sie "genau wie angegeben" möchten, ist dies aus Sicht der Standards von Vorteil, numericda es niemals präziser gespeichert wird, als Sie es gewünscht haben
Ed Avis
13

Keine vollständige Antwort, aber ein nützlicher Link:

"Ich berechne häufig anhand von Dezimalwerten. In einigen Fällen führt das Umsetzen von Dezimalwerten auf Float so schnell wie möglich vor Berechnungen zu einer besseren Genauigkeit."

http://sqlblog.com/blogs/alexander_kuznetsov/archive/2008/12/20/for-better-precision-cast-decimals-before-calculations.aspx

AK
quelle
2
Es macht keinen Sinn. Alle anderen Antworten mit Quellen besagen, dass numerische oder dezimale Datentypen genau sind und Float- oder Real-Typen eine sehr enge Annäherung sind. Aufgrund der geringeren Genauigkeit kann ich verstehen, dass das Gießen zum Schweben schnellere Berechnungen ermöglichen kann, jedoch keine höhere Präzision.
Cbaldan
3
Bei allen numerischen Datentypen kann es zu einem Über- und Unterlauf kommen. Überlauf ist ein expliziter Fehler, Unterlauf ist jedoch stumm. Die Eigenschaften des Unterlaufs für decimalund floatsind unterschiedlich . Die Dezimalstelle schützt so weit wie möglich vor Unterlauf, indem die Genauigkeit oder Skalierung erhöht wird. Sobald Sie jedoch die Grenze für signifikante Dezimalstellen erreicht haben, sind die Unterläufe stumm (und die Genauigkeit geht verloren). Float hat einen größeren Skalierungsbereich und die Skalierungsbeschränkungen sind tatsächlich die Ursache für den Unterlauf. Somit kann der Schwimmer eine bessere Skalierung haben. Trotzdem ist es immer noch ein ungenauer Typ.
ErikE
13

Sie unterscheiden sich in der Priorität des Datentyps

Dezimal und Numerisch sind funktional gleich , es gibt jedoch immer noch Vorrang vor Datentypen , was in einigen Fällen von entscheidender Bedeutung sein kann.

SELECT SQL_VARIANT_PROPERTY(CAST(1 AS NUMERIC) + CAST(1 AS DECIMAL),'basetype')

Der resultierende Datentyp ist numerisch, da er Vorrang vor dem Datentyp hat .

Vollständige Liste der Datentypen nach Priorität:

Referenzlink

Stephan
quelle
7

Dezimal hat eine feste Genauigkeit, während float eine variable Genauigkeit hat.

BEARBEITEN (die gesamte Frage konnte nicht gelesen werden): Float (53) (auch bekannt als real) ist eine Gleitkommazahl mit doppelter Genauigkeit (32 Bit) in SQL Server. Regular Float ist eine Gleitkommazahl mit einfacher Genauigkeit. Double ist eine gute Kombination aus Präzision und Einfachheit für viele Berechnungen. Sie können eine Zahl mit sehr hoher Genauigkeit mit Dezimalzahl erstellen - bis zu 136 Bit -, aber Sie müssen auch darauf achten, dass Sie Ihre Genauigkeit und Skalierung korrekt definieren, damit sie alle Ihre Zwischenberechnungen auf die erforderliche Anzahl von Stellen enthalten kann.

Brian Reiter
quelle
Sie haben nicht angegeben, was vorzuziehen ist, während der Fall für Finanztransaktionen gilt, und warum?
priyanka.sarkar
Für SQL Server 2008 und höher ist float (53) aka float eine Gleitkommazahl mit doppelter Genauigkeit (64 Bit), während float (24) aka real eine Gleitkommazahl mit einfacher Genauigkeit (32 Bit) ist. docs.microsoft.com/en-us/sql/t-sql/data-types/float-and-real-transact-sql
M Kloster
4

Float ist ein Datentyp mit ungefährer Anzahl. Dies bedeutet, dass nicht alle Werte im Datentypbereich genau dargestellt werden können.

Dezimal / Numerisch ist ein Datentyp mit fester Präzision. Dies bedeutet, dass alle Werte im Datentypbereich exakt und präzise dargestellt werden können. Sie können Dezimalstellen verwenden, um Geld zu sparen.

Das Konvertieren von Dezimal oder Numerisch in Float kann zu Genauigkeitsverlusten führen. Für die Datentypen Dezimal oder Numerisch betrachtet SQL Server jede bestimmte Kombination aus Genauigkeit und Skalierung als einen anderen Datentyp. DECIMAL (2,2) und DECIMAL (2,4) sind unterschiedliche Datentypen. Dies bedeutet, dass 11.22 und 11.2222 unterschiedliche Typen sind, obwohl dies bei float nicht der Fall ist. Für FLOAT (6) sind 11.22 und 11.2222 dieselben Datentypen.

Sie können auch den Gelddatentyp verwenden, um Geld zu sparen. Dies ist ein nativer Datentyp mit 4-stelliger Genauigkeit für Geld. Die meisten Experten bevorzugen diesen Datentyp, um Geld zu sparen.

Referenz 1 2 3

Somnath Muluk
quelle
3

Der Fall für Dezimal

Was ist das zugrunde liegende Bedürfnis?

Es ergibt sich aus der Tatsache, dass Computer letztendlich intern Zahlen im Binärformat darstellen. Das führt zwangsläufig zu Rundungsfehlern.

Bedenken Sie:

0.1 (decimal, or "base 10") = .00011001100110011... (binary, or "base 2")

Die obige Ellipse [...] bedeutet "unendlich". Wenn Sie es sich genau ansehen, gibt es ein sich unendlich wiederholendes Muster (= '0011').

Irgendwann muss der Computer diesen Wert also runden. Dies führt zu Akkumulationsfehlern, die sich aus der wiederholten Verwendung von Zahlen ergeben, die ungenau gespeichert sind.

Angenommen, Sie möchten finanzielle Beträge speichern (Zahlen, die möglicherweise einen Bruchteil ausmachen). Erstens können Sie offensichtlich keine ganzen Zahlen verwenden (ganze Zahlen haben keinen Bruchteil). Aus rein mathematischer Sicht wäre die natürliche Tendenz, a zu verwendenfloat . In einem Computer haben Floats jedoch den Teil einer Zahl, der nach einem Dezimalpunkt liegt - die "Mantisse" - begrenzt. Das führt zu Rundungsfehlern.

Um dies zu überwinden, bieten Computer bestimmte Datentypen an, die den binären Rundungsfehler in Computern für Dezimalzahlen begrenzen. Dies ist der Datentyp, der unbedingt zur Darstellung von Finanzbeträgen verwendet werden sollte. Diese Datentypen tragen normalerweise den Namen Decimal. Dies ist beispielsweise in C # der Fall. Oder DECIMALin den meisten Datenbanken.

Varus Septimus
quelle
1

Obwohl die Frage nicht den MONEY-Datentyp enthielt, könnten einige Personen, die auf diesen Thread stoßen, versucht sein, den MONEY-Datentyp für Finanzberechnungen zu verwenden.

Seien Sie vorsichtig mit dem Datentyp MONEY, der nur eine begrenzte Genauigkeit aufweist.

Die Antworten auf diese Stackoverflow-Frage enthalten viele gute Informationen dazu:

Sollten Sie die Datentypen MONEY oder DECIMAL (x, y) in SQL Server auswählen?

Simon Tewsi
quelle