Diferencia entre numérico, flotante y decimal en SQL Server

322

¿Cuáles son las diferencias entre numeric, floaty decimaltipos de datos y que se deben usar en qué situaciones?

Para cualquier tipo de transacción financiera (por ejemplo, para el campo salarial), ¿cuál es la preferida y por qué?

priyanka.sarkar
fuente
1
El enlace decimal y numérico anterior necesita actualizarse a docs.microsoft.com/en-us/sql/t-sql/data-types/… . El enlace de arriba ya no existe.
Nigel Ainscoe
1
Por lo general, cuando se trata de temas financieros es interesante trabajar con tipos enteros , aparte de los de punto flotante , y almacenar los valores como centavos , en lugar de dólares , por ejemplo.
Pedro

Respuestas:

494

use los tipos de datos flotantes o reales solo si la precisión proporcionada por el decimal (hasta 38 dígitos) es insuficiente

  • Los tipos de datos numéricos aproximados no almacenan los valores exactos especificados para muchos números; almacenan una aproximación extremadamente cercana del valor ( Technet )

  • Evite utilizar columnas flotantes o reales en las condiciones de búsqueda de la cláusula WHERE, especialmente los operadores = y <> ( Technet )

generalmente, porque la precisión proporcionada por el decimal es [10E38 ~ 38 dígitos] si su número puede caber en él, y un espacio de almacenamiento más pequeño (y tal vez la velocidad) de Float no es importante y no se trata de comportamientos anormales y problemas de tipos numéricos aproximados aceptable, use Decimal en general .

más información útil

  • numérico = decimal (5 a 17 bytes) ( Tipo de datos numéricos exactos )
    • se asignará a Decimal en .NET
    • ambos tienen (18, 0) parámetros predeterminados (precisión, escala) en el servidor SQL
    • escala = número máximo de dígitos decimales que se pueden almacenar a la derecha del punto decimal.
    • tenga en cuenta que money (8 byte) y smallmoney (4 byte) también son exactos y se asignan a Decimal In .NET y tienen 4 puntos decimales ( MSDN )
    • decimal y numérico (Transact-SQL) - MSDN
  • real (4 bytes) ( tipo de datos numéricos aproximado )
  • flotante (8 bytes) ( tipo de datos numéricos aproximado )
    • se asignará a Double en .NET
  • Todos los tipos numéricos exactos siempre producen el mismo resultado, independientemente de qué tipo de arquitectura de procesador se esté utilizando o la magnitud de los números
  • El parámetro suministrado al tipo de datos flotante define el número de bits que se utilizan para almacenar la mantisa del número de coma flotante .
  • El tipo de datos numéricos aproximado generalmente usa menos almacenamiento y tiene una mejor velocidad (hasta 20x) y también debe considerar cuándo se convirtieron en .NET

Tipos de datos numéricos exactos Tipos de datos numéricos aproximados

fuente principal : MCTS Self-Paced Training Kit (examen 70-433): Desarrollo de bases de datos Microsoft® SQL Server® 2008 - Capítulo 3 - Tablas, tipos de datos e integridad declarativa de datos Lección 1 - Elección de tipos de datos (directrices) - Página 93

Iman
fuente
17
use the float or real data types only if the precision provided by decimal is insufficient- Pensé que real es MENOS exacto que decimal, entonces, ¿cómo es que escribes para usar real si el decimal es insuficiente?
BornToCode
77
real es menos preciso por lo que no se recomienda a menos que el almacenamiento de grandes números más grandes que las consideraciones decimales (> 10e38) que se necesita o espacio .i adivinar la precisión aquí en la cita de valores posibles y magnitud no la exactitud
Iman
12
@BornToCode La "precisión" aquí se refiere a cuán amplios son los valores que desea almacenar. Si necesita almacenar valores entre 1e10 y 1e-10, entonces decimalestará bien. Esa es una precisión de 20. Si necesita almacenar valores entre, digamos, 1e20 y 1e-20, bueno, decimal no puede hacer eso. Eso es 40 dígitos de precisión. Nunca puede almacenar 1e20 y 1e-20 en el mismo decimalcampo. En su lugar, puede usar float, que almacena internamente todo como un registro de la base 2. Eso permite un rango completo de precisión en un campo con el inconveniente de que solo los primeros ~ 8 dígitos serán precisos.
Bacon Bits
Tercero los comentarios de BornToCode e Iman. Acabo de experimentar (usando SQL Server 2012), y parece que la máquina épsilon para float (53), el tipo de punto flotante de mayor precisión, es 2.22044604925031E-16. Entonces obtendrías alrededor de 15 cifras significativas. Por otro lado, puedo obtener 38 cifras significativas de decimal.
Stewart
"Usa el float..." - dijo quién? ¿Es una cita o tu opinión?
user443854
24

Pautas de MSDN: uso de datos decimales, flotantes y reales

La precisión máxima predeterminada de los tipos de datos numéricos y decimales es 38. En Transact-SQL, numérico es funcionalmente equivalente al tipo de datos decimal. Use el tipo de datos decimales para almacenar números con decimales cuando los valores de datos se deben almacenar exactamente como se especifica.

El comportamiento de flotante y real sigue la especificación IEEE 754 en tipos de datos numéricos aproximados. Debido a la naturaleza aproximada de los tipos de datos flotantes y reales, no use estos tipos de datos cuando se requiera un comportamiento numérico exacto, como en aplicaciones financieras, en operaciones que involucran redondeo o en verificaciones de igualdad. En su lugar, use los tipos de datos de entero, decimal, dinero o smallmoney. Evite utilizar columnas flotantes o reales en las condiciones de búsqueda de la cláusula WHERE, especialmente los operadores = y <>. Es mejor limitar las columnas flotantes y reales a comparaciones> o <.

kmote
fuente
El número (fijo) de decimales se especifica en la Scalecolumna.
Cees Timmerman
1
Si desea "exactamente como se especifica", entonces, desde el punto de vista estándar, hay alguna ventaja numericya que nunca se almacenará con más precisión de lo que solicitó: consulte stackoverflow.com/a/759606/626804
Ed Avis
13

No es una respuesta completa, sino un enlace útil:

"Frecuentemente hago cálculos con valores decimales. En algunos casos, emitir valores decimales para flotar lo antes posible, antes de cualquier cálculo, produce una mayor precisión".

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

Alaska
fuente
2
No tiene sentido Todas las demás respuestas, con fuentes, dicen que los tipos de datos numéricos o decimales son precisos, y los tipos flotantes o reales son una aproximación muy cercana. Debido a la menor precisión, puedo entender que lanzar a flotación puede permitir cálculos más rápidos, pero no una mayor precisión.
cbaldan
3
Todos los tipos de datos numéricos pueden experimentar desbordamiento y desbordamiento. El desbordamiento es un error explícito, sin embargo, el desbordamiento es silencioso. Las características del flujo inferior para decimaly floatson diferentes . Preservaciones decimales contra el desbordamiento tanto como sea posible al aumentar la precisión o la escala. Sin embargo, una vez que alcanza el límite de dígitos significativos en decimal, los flujos subyacentes son silenciosos (y se pierde precisión). El flotador tiene un rango de escala más amplio posible, y sus limitaciones de escala son en realidad la causa del desbordamiento. Por lo tanto, el flotador puede tener una mejor escala. No obstante, sigue siendo un tipo inexacto .
ErikE
13

Difieren en precedencia de tipo de datos

Decimal y numérico son los mismos funcionalmente, pero todavía hay precedencia de tipo de datos , que puede ser crucial en algunos casos.

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

El tipo de datos resultante es numérico porque tiene prioridad sobre el tipo de datos .

Lista exhaustiva de tipos de datos por precedencia:

Link de referencia

Stephan
fuente
7

Decimal tiene una precisión fija mientras que flotante tiene precisión variable.

EDITAR (no se pudo leer la pregunta completa): Float (53) (también conocido como real) es un número de coma flotante de doble precisión (32 bits) en SQL Server. Regular Float es un número de coma flotante de precisión simple. Double es una buena combinación de precisión y simplicidad para muchos cálculos. Puede crear un número de muy alta precisión con decimal, hasta 136 bits, pero también debe tener cuidado de definir su precisión y escala correctamente para que pueda contener todos sus cálculos intermedios con el número necesario de dígitos.

Brian Reiter
fuente
No especificó cuál es preferible mientras el caso corresponde a una transacción financiera y por qué.
priyanka.sarkar
Para SQL Server 2008 y versiones posteriores, float (53) aka float es un número de coma flotante de doble precisión (64 bits), mientras que float (24) aka real es un número de coma flotante de precisión simple (32 bits). docs.microsoft.com/en-us/sql/t-sql/data-types/float-and-real-transact-sql
M Kloster
4

Flotante es el tipo de datos de número aproximado, lo que significa que no todos los valores en el rango de tipo de datos se pueden representar exactamente.

Decimal / Numérico es un tipo de datos de precisión fija, lo que significa que todos los valores en el rango de tipo de datos se pueden representar exactamente con precisión y escala. Puede usar decimal para ahorrar dinero.

La conversión de decimal o numérico a flotante puede causar cierta pérdida de precisión. Para los tipos de datos decimales o numéricos, SQL Server considera cada combinación específica de precisión y escala como un tipo de datos diferente. DECIMAL (2,2) y DECIMAL (2,4) son diferentes tipos de datos. Esto significa que 11.22 y 11.2222 son tipos diferentes, aunque este no es el caso de flotante. Para FLOAT (6) 11.22 y 11.2222 son los mismos tipos de datos.

También puede usar el tipo de datos de dinero para ahorrar dinero. Este es un tipo de datos nativo con precisión de 4 dígitos por dinero. La mayoría de los expertos prefiere este tipo de datos para ahorrar dinero.

Referencia 1 2 3

Somnath Muluk
fuente
3

El caso de Decimal

¿Cuál es la necesidad subyacente?

Surge del hecho de que, en última instancia, las computadoras representan, internamente, números en formato binario. Eso conduce, inevitablemente, a errores de redondeo.

Considera esto:

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

La elipsis anterior [...] significa 'infinito'. Si lo miras detenidamente, hay un patrón de repetición infinito (= '0011')

Entonces, en algún momento la computadora tiene que redondear ese valor. Esto conduce a errores de acumulación derivados del uso repetido de números que se almacenan de manera inexacta.

Supongamos que desea almacenar importes financieros (que son números que pueden tener una parte fraccional). Primero que nada, no puedes usar enteros obviamente (los enteros no tienen una parte fraccional). Desde un punto de vista puramente matemático, la tendencia natural sería utilizar a float. Pero, en una computadora, los flotadores tienen la parte de un número que se encuentra después de un punto decimal, la "mantisa", limitada. Eso lleva a errores de redondeo.

Para superar esto, las computadoras ofrecen tipos de datos específicos que limitan el error de redondeo binario en las computadoras para números decimales. Estos son el tipo de datos que deben usarse absolutamente para representar montos financieros. Estos tipos de datos suelen tener el nombre de Decimal. Ese es el caso en C #, por ejemplo. O, DECIMALen la mayoría de las bases de datos.

Varus Septimus
fuente
1

Aunque la pregunta no incluyó el tipo de datos DINERO, algunas personas que se encuentran con este hilo podrían verse tentadas a usar el tipo de datos DINERO para los cálculos financieros.

Tenga cuidado con el tipo de datos MONEY, es de precisión limitada.

Hay mucha buena información al respecto en las respuestas a esta pregunta de Stackoverflow:

¿Debería elegir los tipos de datos DINERO o DECIMAL (x, y) en SQL Server?

Simon Tewsi
fuente