SQL Server에서 숫자, 부동 및 소수의 차이점


322

사이의 차이점은 무엇입니까 numeric, float그리고 decimal어떤 상황에서 사용해야 데이터 유형과는?

어떤 종류의 금융 거래 (예 : 급여 분야)에서 어떤 거래가 선호되며 왜 그런가?


1
위의 십진수 및 숫자 링크는 docs.microsoft.com/en-us/sql/t-sql/data-types/…로 업데이트해야 합니다 . 위의 링크가 더 이상 존재하지 않습니다.
Nigel Ainscoe

1
일반적으로 재무 주제를 처리 할 때 부동 소수점 유형을 제외 하고 정수 유형 을 사용하여 작업하는 것이 흥미롭고 값 을 달러 대신 센트로 저장합니다 .
Pedro

답변:


494

소수점 이하 자릿수 (최대 38 자리)로 제공되는 정밀도 가 충분하지 않은 경우에만 float 또는 real 데이터 형식을 사용하십시오.

  • 대략적인 숫자 데이터 형식은 많은 숫자에 지정된 정확한 값을 저장하지 않습니다 . 그들은 값 의 매우 가까운 근사값을 저장 합니다 . ( Technet )

  • WHERE 절 검색 조건, 특히 = 및 <> 연산자 ( Technet ) 에서 float 또는 real 열을 사용하지 마십시오.

따라서 일반적으로 십진수제공되는 정밀도는 숫자 가 [10E38 ~ 38 자리]이므로 플로트의 작은 저장 공간 (및 아마도 속도)은 중요하지 않으며 비정상적인 동작과 대략적인 숫자 유형 문제는 다루지 않습니다. 허용되는 경우 일반적으로 Decimal을 사용하십시오 .

더 유용한 정보

  • 숫자 = 10 진수 ( 5-17 바이트) ( 정확한 숫자 데이터 유형)
    • .NET에서 Decimal에 매핑됩니다.
    • 둘 다 SQL 서버에서 기본 (정밀도, 스케일) 매개 변수로 (18, 0)을 갖습니다.
    • scale = 소수점 오른쪽에 저장할 수있는 최대 소수점 자릿수입니다.
    • 친절하게도 money (8 byte)와 smallmoney (4 byte)도 정확하고 .NET에서 Decimal에 매핑되며 소수점 4 자리 ( MSDN )입니다.
    • 10 진수 및 숫자 (Transact-SQL)-MSDN
  • 실수 (4 바이트) ( 대략적인 숫자 데이터 유형)
  • float (8 바이트) ( 대략적인 숫자 데이터 유형)
    • .NET에서 Double에 매핑됩니다.
  • 사용되는 프로세서 아키텍처의 종류 또는 숫자의 크기에 관계없이 모든 정확한 숫자 유형은 항상 동일한 결과를 생성합니다
  • float 데이터 형식에 제공되는 매개 변수 는 부동 소수점 숫자가수 를 저장하는 데 사용되는 비트 수를 정의합니다 .
  • 대략적인 숫자 데이터 유형은 일반적으로 스토리지를 덜 사용하고 더 나은 속도 (최대 20 배)를 가지며 .NET에서 변환 될 때도 고려해야합니다.

정확한 숫자 데이터 유형 대략적인 숫자 데이터 유형

주요 출처 : MCTS자가 학습 교육 키트 (시험 70-433) : Microsoft® SQL Server® 2008 데이터베이스 개발 -3 장-테이블, 데이터 유형 및 선언적 데이터 무결성 레슨 1-데이터 유형 선택 (가이드 라인) -Page 93


17
use the float or real data types only if the precision provided by decimal is insufficient-실수가 소수보다 정확하지 않다고 생각했습니다. 소수가 충분하지 않으면 어떻게 실수를 사용합니까?
BornToCode

7
실수는 정확도가 떨어 지므로 10 진수 (> 10e38)보다 큰 큰 숫자를 저장하거나 공간을 고려하지 않는 한 권장하지 않습니다. 인용 부호의 정확도는 정확도가 아닌 가능한 값과 크기를 의미합니다
Iman

12
@BornToCode 여기서 "정밀도"는 저장하려는 값의 범위를 나타냅니다. 1e10과 1e-10 사이의 값을 저장해야한다면 decimal괜찮을 것입니다. 정밀도는 20입니다. 예를 들어 1e20과 1e-20 사이의 값을 저장해야 할 경우 decimal 에는 그렇게 할 수 없습니다 . 40 자리의 정밀도입니다. 같은 decimal필드 에 1e20과 1e-20을 저장할 수 없습니다 . 대신을 사용하여 float모든 것을 기본 2의 로그로 저장합니다. 그러면 첫 번째 ~ 8 자리 만 정확하다는 단점이있는 한 필드에서 전체 범위의 정밀도를 허용합니다.
베이컨 비트

나는 세 번째 BornToCode와 Iman의 의견입니다. 방금 SQL Server 2012를 사용하여 실험했으며 고정밀도 부동 소수점 유형 인 float (53)의 컴퓨터 epsilon은 2.22044604925031E-16입니다. 따라서 약 15 개의 유효 숫자를 얻을 수 있습니다. 다른 한편으로, 나는 십진수에서 38의 유효 숫자를 얻을 수 있습니다.
Stewart

"사용 float..."-누가 말했다? 그 말이 당신의 의견입니까?
user443854

24

MSDN의 지침 : 10 진수, 부동 및 실제 데이터 사용

숫자 및 소수 데이터 형식의 기본 최대 정밀도는 38입니다. Transact-SQL에서 숫자는 기능적으로 소수 데이터 형식과 같습니다. 데이터 값을 지정된대로 정확하게 저장해야하는 경우 10 진수 데이터 유형을 사용하여 숫자를 10 진수로 저장하십시오.

float 및 real의 동작은 대략적인 숫자 데이터 형식에 대한 IEEE 754 사양을 따릅니다. float 및 real 데이터 형식의 대략적인 특성으로 인해 재무 응용 프로그램, 반올림 관련 작업 또는 동등 검사와 같은 정확한 숫자 동작이 필요한 경우 이러한 데이터 형식을 사용하지 마십시오. 대신 정수, 10 진수, 돈 또는 smallmoney 데이터 형식을 사용하십시오. WHERE 절 검색 조건, 특히 = 및 <> 연산자에서 float 또는 real 열을 사용하지 마십시오. float 및 real 열을> 또는 <비교로 제한하는 것이 가장 좋습니다.


Scale열에 (고정 된) 소수 자릿수가 지정 됩니다.
Cees Timmerman

1
'정확하게 지정된대로'원하는 경우 표준 관점에서 numeric요구 한 것보다 더 정확하게 저장하지 않기 때문에 몇 가지 이점 이 있습니다. stackoverflow.com/a/759606/626804
Ed Avis

13

완전한 답변은 아니지만 유용한 링크 :

"소수점에 대한 계산을 자주합니다. 어떤 경우에는 계산하기 전에 최대한 빨리 부동 소수점으로 소수 값을 캐스트하면 정확도가 향상됩니다."

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


2
말이되지 않습니다. 소스를 사용하는 다른 모든 대답은 숫자 또는 십진 데이터 유형이 정확하고 부동 또는 실제 유형은 매우 가까운 근사치라고 말합니다. 정확도가 낮아서 플로팅으로 캐스팅하면 더 빠른 계산이 가능하지만 정밀도는 높지 않을 수 있음을 이해할 수 있습니다.
cbaldan

3
모든 숫자 데이터 형식은 오버플로 및 언더 플로를 경험할 수 있습니다. 오버플로는 명백한 오류이지만 언더 플로는 조용합니다. 언더 플로의 특성 decimalfloat다릅니다 . 십진법은 정밀도 또는 스케일을 증가시켜 언더 플로를 최대한 방지합니다. 그러나 십진수로 유효 자릿수 한도에 도달하면 언더 플로는 소리가 나지 않으며 정밀도가 손실됩니다. Float는 가능한 넓은 범위의 스케일을 가지고 있으며 실제로 언더 플로의 원인 인 스케일 제한입니다. 따라서 float는 더 나은 스케일을 가질 수 있습니다. 그럼에도 불구하고 여전히 부정확 한 유형입니다.
ErikE 2016 년

13

데이터 형식 우선 순위가 다릅니다

십진법숫자기능적으로 동일 하지만 여전히 데이터 유형 우선 순위 가 있으며 일부 경우에 중요 할 수 있습니다.

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

결과 데이터 유형은 데이터 유형이 우선 하므로 숫자 입니다.

우선 순위 별 전체 데이터 유형 목록 :

참조 링크


7

십진법은 정밀도가 고정 된 반면 float는 가변 정밀도입니다.

편집 (전체 질문을 읽지 못했습니다) : Float (53) (일명 실제)는 SQL Server의 배정도 (32 비트) 부동 소수점 숫자입니다. 일반 부동은 단 정밀도 부동 소수점 숫자입니다. Double은 많은 계산에서 정밀도와 단순성의 좋은 조합입니다. 소수점 이하 136 비트까지 매우 높은 정밀도 숫자를 만들 수 있지만 정밀도와 스케일을 올바르게 정의하여 필요한 모든 자릿수까지 모든 중간 계산을 포함 할 수 있도록주의해야합니다.


사건이 금융 거래를 진행하는 동안 선호되는 이유와 이유를 지정하지 않았습니까?
priyanka.sarkar 2016 년

SQL Server 2008 이상에서 float (53) 일명 float는 배정도 (64 비트) 부동 소수점 숫자이며 float (24) 일명 real은 단 정밀도 (32 비트) 부동 소수점 숫자입니다. docs.microsoft.com/ko-kr/sql/t-sql/data-types/float-and-real-transact-sql
M Kloster

4

Float 은 근사 숫자 데이터 형식이므로 데이터 형식 범위의 모든 값을 정확하게 표현할 수는 없습니다.

10 진수 / 숫자 는 고정밀도 데이터 형식입니다. 즉, 데이터 형식 범위의 모든 값을 정밀도와 스케일로 정확하게 표현할 수 있습니다. 돈 절약을 위해 십진수를 사용할 수 있습니다.

10 진수 또는 숫자에서 부동 소수점으로 변환하면 정밀도가 약간 떨어질 수 있습니다. 10 진수 또는 숫자 데이터 형식의 경우 SQL Server는 정밀도와 스케일의 각 특정 조합을 다른 데이터 형식으로 간주합니다. DECIMAL (2,2) 및 DECIMAL (2,4)는 다른 데이터 유형입니다. 이것은 float의 경우가 아니지만 11.22와 11.2222는 다른 유형임을 의미합니다. FLOAT (6) 11.22 및 11.2222의 경우 동일한 데이터 유형입니다.

을 절약 하기 위해 돈 데이터 유형을 사용할 수도 있습니다 . 이것은 돈을 위해 4 자리 정밀도의 기본 데이터 형식입니다. 대부분의 전문가는 비용 절감을 위해이 데이터 유형을 선호합니다.

참조 1 2 3


3

십진수의 경우

근본적인 요구는 무엇입니까?

궁극적으로 컴퓨터는 내부적으로 숫자를 이진 형식으로 나타냅니다. 필연적으로 반올림 오류가 발생합니다.

이걸 고려하세요:

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

위의 줄임표 (...)는 '무한'을 의미합니다. 주의 깊게 살펴보면 무한 반복 패턴이 있습니다 (= '0011')

따라서 어느 시점에서 컴퓨터는 그 값을 반올림해야합니다. 이는 부정확하게 저장된 숫자의 반복 된 사용으로 인한 누적 오류를 초래합니다.

재무 금액 (소수 부분을 가질 수있는 숫자)을 저장하려고한다고 가정하십시오. 우선 정수를 분명히 사용할 수 없습니다 (정수에는 소수 부분이 없습니다). 순전히 수학적인 관점에서 자연적인 경향은을 사용하는 것 float입니다. 그러나 컴퓨터에서 플로트는 소수점 뒤에 "숫자"가있는 숫자의 일부를 가지고 있습니다. 반올림 오류가 발생합니다.

이를 극복하기 위해 컴퓨터는 컴퓨터에서 이진수 반올림 오류를 10 진수로 제한하는 특정 데이터 유형을 제공합니다. 이들은 재무 금액을 나타내는 데 절대적으로 사용해야하는 데이터 유형입니다. 이러한 데이터 유형은 일반적으로 이름으로 사용 Decimal됩니다. 예를 들어 C #의 경우입니다. 또는 DECIMAL대부분의 데이터베이스에서.


당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.