Differenza tra numerico, float e decimale in SQL Server


322

Quali sono le differenze tra numeric, floate decimaltipi di dati e che dovrebbero essere usati in quali situazioni?

Per qualsiasi tipo di transazione finanziaria (ad esempio per il campo salariale), quale è preferito e perché?


1
Il collegamento decimale e numerico sopra deve essere aggiornato a docs.microsoft.com/en-us/sql/t-sql/data-types/… . Il link sopra non esiste più.
Nigel Ainscoe,

1
Di solito, quando si tratta di soggetti finanziari interessa a lavoro con Integer tipi, oltre a virgola mobile quelli, e memorizzare i valori come centesimi , invece di dollari , per esempio.
Pedro,

Risposte:


494

utilizzare il tipo float o dati reali solo se la precisione fornita dal decimale (fino a 38 cifre) è insufficiente

  • I tipi di dati numerici approssimativi non memorizzano i valori esatti specificati per molti numeri; memorizzano un'approssimazione estremamente stretta del valore. ( Technet )

  • Evitare di utilizzare colonne mobili o reali nelle condizioni di ricerca della clausola WHERE, in particolare gli operatori = e <> ( Technet )

quindi in genere perché la precisione fornita dal decimale è [10E38 ~ 38 cifre] se il numero può adattarsi al suo interno, e lo spazio di archiviazione più piccolo (e forse la velocità) di Float non è importante e gestire comportamenti anomali e problemi di tipo numerico approssimativo non lo è accettabile, usare Decimal in generale .

informazioni più utili

  • numerico = decimale (da 5 a 17 byte) (tipo esatto di dati numerici)
    • verrà mappato su Decimale in .NET
    • entrambi hanno (18, 0) come parametri predefiniti (precisione, scala) nel server SQL
    • scala = numero massimo di cifre decimali che possono essere memorizzate a destra del punto decimale.
    • si prega di notare che anche i soldi (8 byte) e smallmoney (4 byte) sono esatti e mappano su Decimal In .NET e hanno 4 punti decimali ( MSDN )
    • decimale e numerico (Transact-SQL) - MSDN
  • reale (4 byte) ( tipo di dati numerico approssimativo )
  • float (8 byte) ( tipo di dati numerico approssimativo )
    • verrà mappato su Double in .NET
  • Tutti i tipi numerici esatti producono sempre lo stesso risultato, indipendentemente dal tipo di architettura del processore utilizzato o dall'entità dei numeri
  • Il parametro fornito al tipo di dati float definisce il numero di bit utilizzati per memorizzare la mantissa del numero in virgola mobile .
  • Il tipo di dati numerico approssimativo di solito utilizza meno spazio di archiviazione e ha una velocità migliore (fino a 20x) e dovresti anche considerare quando sono stati convertiti in .NET

Tipi di dati numerici esatti Tipi di dati numerici approssimativi

fonte principale : Kit di formazione autonomo MCTS (Esame 70-433): Sviluppo del database Microsoft® SQL Server® 2008 - Capitolo 3 - Tabelle, tipi di dati e integrità dei dati dichiarativi Lezione 1 - Scelta dei tipi di dati (Linee guida) - Pagina 93


17
use the float or real data types only if the precision provided by decimal is insufficient- Pensavo che reale fosse MENO accurato quindi decimale, quindi come mai scrivi per usare reale se il decimale è insufficiente?
BornToCode

7
reale è meno accurato, quindi non è raccomandato a meno che non sia necessario memorizzare numeri grandi più grandi di decimali (> 10e38) o considerazioni di spazio. Immagino che la precisione qui nella citazione significhi possibili valori e grandezza non l'accuratezza
Iman

12
@BornToCode La "precisione" qui si riferisce all'ampiezza dei valori che si desidera memorizzare. se hai bisogno di memorizzare valori tra 1e10 e 1e-10, allora decimalandrà bene. Questa è una precisione di 20. Se hai bisogno di memorizzare valori tra, diciamo, 1e20 e 1e-20, beh, decimal non puoi farlo. Sono 40 cifre di precisione. Non puoi mai memorizzare 1e20 e 1e-20 nello stesso decimalcampo. Invece, è possibile utilizzare float, che memorizza internamente tutto come un registro di base 2. Ciò consente una gamma completa di precisione in un campo con l'inconveniente che solo le prime ~ 8 cifre saranno accurate.
Pezzi di pancetta

Terzo dei commenti di BornToCode e Iman. Ho appena sperimentato (usando SQL Server 2012) e sembra che la macchina epsilon per float (53), il tipo a virgola mobile di massima precisione, sia 2.22044604925031E-16. Quindi otterresti circa 15 cifre significative da esso. D'altra parte, posso ottenere 38 cifre significative dal decimale.
Stewart,

"Usa il float..." - disse chi? È una citazione o la tua opinione?
user443854,

24

Linee guida da MSDN: utilizzo di dati decimali, mobili e reali

La precisione massima predefinita dei tipi di dati numerici e decimali è 38. In Transact-SQL, numerico è funzionalmente equivalente al tipo di dati decimali. Utilizzare il tipo di dati decimali per memorizzare numeri con decimali quando i valori dei dati devono essere memorizzati esattamente come specificato.

Il comportamento di float e real segue la specifica IEEE 754 sui tipi di dati numerici approssimativi. A causa della natura approssimativa del float e dei tipi di dati reali, non utilizzare questi tipi di dati quando è richiesto un comportamento numerico esatto, ad esempio nelle applicazioni finanziarie, nelle operazioni di arrotondamento o nei controlli di uguaglianza. Utilizzare invece i tipi di dati interi, decimali, monetari o smallmoney. Evitare di utilizzare colonne mobili o reali nelle condizioni di ricerca della clausola WHERE, in particolare gli operatori = e <>. È consigliabile limitare il float e le colonne reali a> o <confronti.


Il numero (fisso) di decimali è specificato nella Scalecolonna.
Cees Timmerman,

1
Se vuoi "esattamente come specificato", allora, dal punto di vista degli standard, c'è qualche vantaggio numericpoiché non verrà mai archiviato con più precisione di quella che hai richiesto: vedi stackoverflow.com/a/759606/626804
Ed Avis

13

Non una risposta completa, ma un link utile:

"Faccio spesso calcoli contro valori decimali. In alcuni casi, lanciando valori decimali per passare al galleggiante al più presto, prima di qualsiasi calcolo, si ottiene una migliore precisione."

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


2
Non ha senso. Tutte le altre risposte, con le fonti, affermano che i tipi di dati numerici o decimali sono precisi e che i tipi float o reali sono un'approssimazione molto stretta. A causa della minore precisione, posso capire che il casting su float può consentire calcoli più rapidi, ma non una precisione maggiore.
cbaldan,

3
Tutti i tipi di dati numerici possono verificarsi overflow e underflow. L'overflow è un errore esplicito, tuttavia il underflow è silenzioso. Le caratteristiche di underflow per decimale floatsono diverse . Il decimale preserva il più possibile dal underflow aumentando la precisione o la scala. Tuttavia, una volta raggiunto il limite di cifre significative in decimale, i underflow diventano silenziosi (e la precisione viene persa). Float ha una gamma più ampia possibile di scala ed è i limiti di scala che in realtà sono la causa del underflow. Pertanto, il galleggiante può avere una scala migliore. Tuttavia, è ancora un tipo inesatto .
ErikE,

13

Differiscono nella precedenza del tipo di dati

Decimale e Numerico sono gli stessi funzionalmente, ma esiste ancora la precedenza del tipo di dati , che può essere cruciale in alcuni casi.

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

Il tipo di dati risultante è numerico perché ha la precedenza sul tipo di dati .

Elenco esaustivo di tipi di dati per precedenza:

Link di riferimento


7

Il decimale ha una precisione fissa mentre il float ha una precisione variabile.

EDIT (impossibile leggere l'intera domanda): Float (53) (aka real) è un numero a virgola mobile a precisione doppia (32 bit) in SQL Server. Il float regolare è un numero in virgola mobile a precisione singola. Il doppio è una buona combinazione di precisione e semplicità per molti calcoli. Puoi creare un numero di precisione molto elevato con decimale - fino a 136 bit - ma devi anche fare attenzione a definire la precisione e ridimensionare correttamente in modo che possa contenere tutti i tuoi calcoli intermedi al numero necessario di cifre.


Non hai specificato quale è preferibile mentre il caso riguarda una transazione finanziaria e perché?
priyanka.sarkar,

Per SQL Server 2008 e versioni successive, float (53) aka float è un numero in virgola mobile a doppia precisione (64 bit), mentre float (24) aka real è un numero in virgola mobile a precisione singola (32 bit). docs.microsoft.com/en-us/sql/t-sql/data-types/float-and-real-transact-sql
M Kloster

4

Float è un tipo di dati con numero approssimativo, il che significa che non tutti i valori nell'intervallo del tipo di dati possono essere rappresentati esattamente.

Decimale / Numerico è un tipo di dati a precisione fissa, il che significa che tutti i valori nell'intervallo del tipo di dati possono essere rappresentati esattamente con precisione e scala. È possibile utilizzare i decimali per risparmiare denaro.

La conversione da decimale o numerico a virgola mobile può causare una perdita di precisione. Per i tipi di dati Decimali o Numerici, SQL Server considera ogni combinazione specifica di precisione e scala come un diverso tipo di dati. DECIMAL (2,2) e DECIMAL (2,4) sono diversi tipi di dati. Ciò significa che 11.22 e 11.2222 sono tipi diversi anche se questo non è il caso di float. Per FLOAT (6) 11.22 e 11.2222 sono gli stessi tipi di dati.

È inoltre possibile utilizzare il tipo di dati denaro per risparmiare denaro. Questo è un tipo di dati nativo con una precisione di 4 cifre per denaro. La maggior parte degli esperti preferisce questo tipo di dati per risparmiare denaro.

Riferimento 1 2 3


3

Il caso del decimale

Di cosa ha bisogno?

Deriva dal fatto che, alla fine, i computer rappresentano, internamente, numeri in formato binario. Ciò comporta inevitabilmente errori di arrotondamento.

Considera questo:

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

I puntini di sospensione sopra [...] significano "infinito". Se lo guardi attentamente, c'è un modello ripetuto infinito (= '0011')

Quindi, ad un certo punto il computer deve arrotondare quel valore. Ciò porta a errori di accumulazione derivanti dall'uso ripetuto di numeri memorizzati in modo inesatto.

Supponi di voler memorizzare importi finanziari (che sono numeri che possono avere una parte frazionaria). Prima di tutto, ovviamente non puoi usare numeri interi (i numeri interi non hanno una parte frazionaria). Da un punto di vista puramente matematico, la tendenza naturale sarebbe quella di usare a float. Ma, in un computer, i float hanno la parte di un numero che si trova dopo un punto decimale - la "mantissa" - limitata. Ciò porta ad errori di arrotondamento.

Per ovviare a questo, i computer offrono tipi di dati specifici che limitano l'errore di arrotondamento binario nei computer per i numeri decimali. Questi sono i tipi di dati che dovrebbero assolutamente essere utilizzati per rappresentare gli importi finanziari. Questi tipi di dati in genere si chiamano Decimal. Questo è il caso in C #, per esempio. O, DECIMALnella maggior parte dei database.


Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.