SQL Server에서 MONEY 또는 DECIMAL (x, y) 데이터 유형을 선택해야합니까?


442

나는 money데이터 유형과 같은 것 decimal(19,4)(돈이 내부적으로 사용하는 것) 사이에 실제 차이가 있는지 궁금합니다 .

moneySQL Server에만 해당되는 것으로 알고 있습니다. 하나를 선택해야 할 강력한 이유가 있는지 알고 싶습니다. 대부분의 SQL Server 샘플 (예 : AdventureWorks 데이터베이스) 은 가격 정보와 같은 용도로 사용 money되지 않습니다 decimal.

money 데이터 유형을 계속 사용해야합니까, 아니면 십진수를 사용하면 이점이 있습니까? 돈은 입력하는 문자 수가 적지 만 유효한 이유는 아닙니다. :)


12
DECIMAL(19, 4) 인기있는 선택입니다 확인 또한 확인 여기에 사용하는 방법을 많은 소수 자릿수를 결정하는 세계 외화 형식, 희망이 도움이됩니다.
shaijut

나는 돈 데이터 유형이 왜 소수점 이하 4 자리 ..가 아닌지 궁금했습니다. 즉 1 달러로 100 센트이므로 소수점 이하 2 자리 만 필요합니까? $ 9999.99보다 적은 금액의 기록을 저장하기 위해 데이터 유형 10 진수 (6,2)를 사용하려고했습니다. 나누기 또는 곱하기 계산, 저장 및 합계에 대해 걱정하지 않습니다 ..
Allan F

답변:


326

절대 돈을 써서는 안됩니다. 그것은 정확하지 않으며 순수한 쓰레기입니다. 항상 10 진수 / 숫자를 사용하십시오.

이것이 무엇을 의미하는지 보려면 이것을 실행하십시오.

DECLARE
    @mon1 MONEY,
    @mon2 MONEY,
    @mon3 MONEY,
    @mon4 MONEY,
    @num1 DECIMAL(19,4),
    @num2 DECIMAL(19,4),
    @num3 DECIMAL(19,4),
    @num4 DECIMAL(19,4)

    SELECT
    @mon1 = 100, @mon2 = 339, @mon3 = 10000,
    @num1 = 100, @num2 = 339, @num3 = 10000

    SET @mon4 = @mon1/@mon2*@mon3
    SET @num4 = @num1/@num2*@num3

    SELECT @mon4 AS moneyresult,
    @num4 AS numericresult

출력 : 2949.0000 2949.8525

돈으로 돈을 나누지 않는다고 말한 사람들에게 :

다음은 상관 관계를 계산하는 쿼리 중 하나이며 돈으로 변경하면 잘못된 결과가 발생합니다.

select t1.index_id,t2.index_id,(avg(t1.monret*t2.monret)
    -(avg(t1.monret) * avg(t2.monret)))
            /((sqrt(avg(square(t1.monret)) - square(avg(t1.monret))))
            *(sqrt(avg(square(t2.monret)) - square(avg(t2.monret))))),
current_timestamp,@MaxDate
            from Table1 t1  join Table1 t2  on t1.Date = traDate
            group by t1.index_id,t2.index_id

61
"Never"는 강력한 단어입니다. "돈"은 문화에 민감한 방식으로 사용자에게 표시하기 위해 결과를 해당 유형으로 캐스트하는 데 유용하지만 계산 자체에는 사용하기가 매우 좋지 않습니다.
Joel Coehoorn 님이

36
아무도 돈 유형의 두 객체를 곱하지 않기 때문에 귀하의 예는 의미가 없습니다. 요점을 증명하려면 돈에 소수를 곱한 것과 소수에 소수점을 곱하는 것을 비교해야합니다.
Brian

27
.. 그러나 왜 돈 * 돈이 돈의 정밀도를 갖지 못하는지는 여전히 수수께끼입니다.
Learning

4
@Learning : 돈의 정밀도가 있습니다. 그러나 시간이 지남에 따라 누적 오류가 계속 발생합니다. 10 진수 유형은 이진 산술을 사용하지 않습니다. 이는 종이에서 수행 할 때와 동일한 기본 10 개의 결과를 얻도록 보장합니다.
Joel Coehoorn 님

55
곱셈과의 구분 money을 통해 money별도로,이 '그림'조작이다. 그것은 문서화 된 사실입니다.money고정되고 매우 제한된 정밀도 가진 . 이러한 경우 먼저 곱한 다음 나눕니다. 이 예제에서 연산자 순서를 변경하면 동일한 결과를 얻을 수 있습니다. A는 money기본적으로 64 비트 int이며 당신이의 int를 다루는 것 인 경우에, 당신은 다중 분할 것입니다 전에.
Andriy M

272

SQLMenace는 돈이 정확하지 않다고 말했다. 그러나 돈을 돈으로 곱하거나 나누지 않습니다! 3 달러 곱하기 50 센트는 얼마입니까? 150 달러 센트? 돈을 스칼라로 곱하거나 나누면 소수점 이하 자릿수 여야합니다.

DECLARE
@mon1 MONEY,
@mon4 MONEY,
@num1 DECIMAL(19,4),
@num2 DECIMAL(19,4),
@num3 DECIMAL(19,4),
@num4 DECIMAL(19,4)

SELECT
@mon1 = 100,
@num1 = 100, @num2 = 339, @num3 = 10000

SET @mon4 = @mon1/@num2*@num3
SET @num4 = @num1/@num2*@num3

SELECT @mon4 AS moneyresult,
@num4 AS numericresult

올바른 결과를 얻습니다.

moneyresult numericresult
--------------------- ----------------------------- ----------
2949.8525 2949.8525

money소수점 이하 4 자리가 필요하지 않은 한 좋으며, 돈을 나타내지 않는 스칼라가 decimals 인지 확인하십시오 .


57
1 달러짜리 동전으로 몇 센트짜리 동전을 얻을 수 있습니까? 이에 대한 답은 돈 / 돈이 필요합니다.
Learning

48
이 경우에 배우는 결과는 돈이 아니라 실수입니다. (기본 치수 분석)
Richard Richard

11
@Learning : 1 달러에 몇 센트를 데이터베이스에 요청합니까? 어쨌든 올바른 결과를 반환합니다. 그의 문제는 돈 / 돈이 4 자리 (0.2949)까지만 정확하다는 것입니다 .10000을 곱하면 2949.0000이되었습니다.
구성자

26
@mson 그는 한 줄의 말을 기반으로 한 것처럼 정확하고 개인적인 비판을하지 않습니다. 도움이되지 않습니다. 그가 $ 0.01로 나누지 않고 0.01 대신 나누면 결과는 100이 아닌 $ 100입니다. $ 100 센트가 아니라 100 센트가 있습니다. 단위가 중요합니다! 다이빙을하고 돈을 곱할 수있는 큰 공간이 있습니다.
andrewb 2016 년

19
36 달러에 주식을 구매하기 위해 1000 달러를 쓰고 싶다면, 합법적 인 사용이 money / money아닙니까? 답은 달러 기호가 첨부되지 않은 전체 단위입니다. 맞습니다! 이것은 매우 합리적인 시나리오이며, 이와 같은 이상한 경우로 인해 정밀도 및 스케일에 대한 일반적인 규칙을 따르는 대신 money결과가 항상 적합하도록 잘려지기 때문에 사용하기에 좋은 데이터 유형이 아니라고 제안합니다 money. money값 집합의 표준 편차를 계산하려면 어떻게합니까? 예, Sqrt(Sum(money * money))(간체 화) 실제로 의미가 있습니다.
ErikE 2016 년

59

무엇을하고 있는지 모른다면 모든 것이 위험합니다

고정밀 소수 유형조차도 하루를 저장할 수 없습니다.

declare @num1 numeric(38,22)
declare @num2 numeric(38,22)
set @num1 = .0000006
set @num2 = 1.0
select @num1 * @num2 * 1000000

1.000000 <-0.6000000이어야합니다


money유형은 정수

의 텍스트 표현 smallmoneydecimal(10,4)비슷하게 보일 수 있지만, 그들이 상호 교환하지 않습니다. 날짜가 저장된 것으로 보았을 때 울부 짖 varchar(10)습니까? 이것은 같은 것입니다.

뒤에서 money/ smallmoney는 단지 bigint/ int 입니다. 텍스트 표현의 소수점 money은 yyyy-mm-dd 날짜의 대시와 마찬가지로 시각적 솜털입니다. SQL은 실제로 내부적으로 저장하지 않습니다.

decimalvs money와 관련 하여 필요에 맞는 것을 선택하십시오. money유닛의 1 / 10,000번째의 정수배로서 차지하는 값을 저장하는 것은 매우 일반적이므로 유형이 존재한다. 또한 단순한 덧셈과 뺄셈을 넘어 실제 돈과 계산을 다루는 경우 데이터베이스 수준에서 그렇게해서는 안됩니다! Banker 's Rounding (IEEE 754) 을 지원하는 라이브러리를 사용하여 애플리케이션 레벨에서 수행하십시오.


1
이 예에서 무슨 일이 있었는지 설명 할 수 있습니까?
Sergey Popov

4
스케일 오버 플로우. 소규모에서 numeric (a, b) * numeric (c, d)는 numeric (a-b + c-d + 1, max (b, d))를 생성합니다. 그러나 (a + b + c + d)> 38 인 경우 SQL은 스케일을 제한하여 분수 측에서 정밀도를 빼내고 정수 측을 채우므로 반올림 오류가 발생합니다.
Anon

모든 수치 계산은 스케일링으로 인한 정밀도 손실에 영향을 받기 쉽습니다. 대신 select select 1000000 * @ num1 * @ num2
Mitch Wheat

Anon의 예는 버전 및 데이터베이스에 따라 다릅니다. 그러나 요점은 유효합니다. sqlanywhere 버전 1.1에서이 예제는 0.600000을 올바르게 제공합니다. (여기서 ms sql에 대해 이야기하고 있음을 알고 있습니다). 다른 데이터베이스에서 돈 유형이 누락되었다는 또 다른 요점은 도메인 생성과 같이 10 진수 또는 숫자를 돈으로 호출하는 방법이 있습니다.
gg89

3
나는 이것이 단순히 전파되는 오류뿐만 아니라 실제로 뒤에서 일어나는 일과 MONEY가 처음에 존재하는 이유를 설명했기 때문에 이것이 가장 현명한 대답이라고 생각합니다. 왜이 답변을 얻는 데 4 년이 걸 렸는지 잘 모르겠지만 아마도 계산 "문제"에 너무 많은 초점을 두었 기 때문일 수도 있고, 왜 돈과 십 대 돈의 이유와 방법에 크게 초점을 맞추지 않았기 때문일 것입니다.
Steve Sether

44

WayneM은 돈이 SQL Server에만 해당된다는 것을 알고 있다고 언급했습니다. 그러나 그는 십진수 이상의 돈을 사용해야 할 이유가 있는지 묻고 있으며 그 반대의 경우도 여전히 분명한 한 가지 이유가 언급되어야한다고 생각합니다. 십진수를 사용한다는 것은 DBMS를 변경해야 할 경우 걱정할 필요가 없다는 것을 의미합니다 -일어날 수있는 일.

시스템을 최대한 유연하게 만드십시오!


1
아마도 이론 상으로는 다른 DBMS (도메인 선언을 지원하는)에서 Money라는 도메인을 선언 할 수 있습니다.
토론자

누군가 현재 SQL Server 데이터베이스를 Amazon Redshift로 변환 할 때 이것이 진짜 문제임을 보증 할 수 있습니다. 비즈니스상의 이유가없는 한 특정 데이터베이스 플랫폼에 맞는 데이터 유형을 피하십시오.
Nathan Griffiths

@Nathn은 PostgreSQL 또는 SQL Server와 비교하여 Redshift의 약한 유형 시스템을 제공합니다. 예를 들어 date유형이 없으면 항상 그러한 문제가 발생 한다고 말하고 싶습니다 . "데이터베이스가 더 나은 표준 호환 유형을 이미 제공하고 더 이상 사용되지 않는 유형 에 대해 경고 하는 경우 더 이상 사용되지 않는 유형을 사용하지 마십시오"라고 말해야합니다 .
Panagiotis Kanavos

@PanagiotisKanavos-돈은 더 이상 사용되지 않습니다
Martin Smith

@MartinSmith는 2017 년에 실제로 BTC와 같은 화폐 가치를 처리 할 수 ​​없기 때문에이를보고 충격을 받았습니다. 어쨌든, Redshift로 이사하면 많은 고통이
초래됩니다

32

글쎄, 난 좋아 MONEY! 이보다 바이트가 저렴 DECIMAL하고 (커버 아래) 더하기 및 빼기 연산은 본질적으로 정수 연산이므로 계산이 더 빠르게 수행됩니다. 알지 못하는 사람에게 큰 경고 인 INT@SQLMenace 의 예제는 예가 될 수있는 egers 에게 동일하게 적용될 수 있습니다. 그러나 이것이 적절한 경우 정수를 사용하지 않는 이유는 없습니다. .

따라서 완벽하게 '안전'하고 MONEY다루는 것이 MONEY사용하는 것이 적절하고 수학적 규칙에 따라 사용하는 것이 적절합니다 (INT 에거 ).

SQL Server MONEYDECIMALs ( 들)로 나누기와 곱셈을 장려한다면 더 좋았을 FLOAT것입니다. 그러나 그들은 이것을 선택하지 않았습니다. 그들은 INT예를 FLOAT나누는 사람들 에게 홍보하도록 선택하지도 않았다 .

MONEY정밀도 문제가 없습니다. 그DECIMAL계산 중에 사용되는 더 큰 중간 유형을 얻는 유형을 사용하는 '기능'일뿐입니다 (실제로 '기능'이 얼마나 멀리 확장되는지 확실하지 않습니다).

구체적인 질문에 답하기 위해 "추천 이유"? 당신은 절대 최대 성능을 원한다면 음, SUM(x)어디 x수 중 수 DECIMAL또는 MONEY다음,MONEY 가장자리를해야합니다.

또한 크기가 SMALLMONEY4 바이트에 불과한 작은 사촌이라는 사실을 잊지 마십시오. 214,748.3647돈이 거의 들지 않는 경우가 많기 때문에 종종 적합하지 않습니다.

더 큰 중간 유형을 사용하는 것에 대한 요점을 증명하기 위해 중간에 변수를 명시 적으로 할당 DECIMAL하면 동일한 문제가 발생합니다.

declare @a decimal(19,4)
declare @b decimal(19,4)
declare @c decimal(19,4)
declare @d decimal(19,4)

select @a = 100, @b = 339, @c = 10000

set @d = @a/@b

set @d = @d*@c

select @d

생성합니다 2950.0000(좋아요, 적어도 잘리지 DECIMAL않고 반올림 됨 MONEY-정수와 동일).


21
MONEY1 바이트 적은보다 DECIMAL 정밀도 19 자리 위로. 그러나 대부분의 실제 통화 계산 (최대 $ 9.99M)은 DECIMAL(9, 2)5 바이트 만 필요한에 적합합니다. 당신은 크기를 저장 반올림 오류에 대해 덜 걱정, 수 코드 이식성합니다.

@JonofAllTrades는 정확하지만, 동전이나 센트를 포함하는 정수를 사용하여 정수 성능을 되찾고 소수점 위치를 인코딩하고 소수점을 더할 때 확인해야하는 추가 바이트를 저장할 수도 있습니다.
dsz

"따라서 다루는 것이 MONEY 일 때 MONEY를 사용하고 그 뒤에 따르는 수학 규칙에 따라 사용하는 것이 완벽하게 '안전'하며 적절합니다."-> 그러나 Anon의 답변도 참조하십시오. 뭘하는지 알아 " 당신은 사람들이 당신이 만들고있는 시스템을 쿼리하는 방법을 결코 예측할 수 없으며, 가능한 한 오용의 가능성을 피하기 위해 최선을 다합니다. 스토리지의 적은 이익은 IMHO의 가치가 없습니다.
Nathan Griffiths

1
비트 코인 값을 저장하십시오. 그것은 8 개의 소수점이 있습니다
Panagiotis Kanavos

14

우리는 방금 비슷한 문제를 겪었고 최상위 프레젠테이션을 제외하고는 Money를 사용하지 않는 것에 대해 +1이되었습니다. 우리는 여러 가지 테이블 (효과적으로 판매 바우처 및 판매 송장)을 가지고 있으며 각 테이블에는 과거의 이유로 인해 하나 이상의 Money 필드가 포함되어 있으며, 총 송장 세금 중 각각이 얼마나 관련되어 있는지 계산하기 위해 비례 계산을 수행해야합니다. 판매 바우처의 라인. 우리의 계산은

vat proportion = total invoice vat x (voucher line value / total invoice value)

이로 인해 실제 돈 / 돈 계산으로 인해 분할 부분에서 스케일 오류가 발생하여 잘못된 vat 비율로 곱해집니다. 이 값이 나중에 추가되면 총 송장 값에 합산되지 않는 VAT 비율의 합계로 끝납니다. 대괄호의 값 중 하나가 10 진수 (나는 그중 하나를 캐스팅하려고합니다)가 vat 비율이 정확했을 것입니다.

대괄호가 원래 작동하지 않았을 때 관련된 큰 값 때문에 효과적으로 더 큰 스케일을 시뮬레이션하고 있다고 생각합니다. 우리는 곱셈을 먼저 수행했기 때문에 대괄호를 추가했습니다. 드물게 계산에 사용할 수있는 정밀도를 날려 버렸지 만 이제는 훨씬 더 일반적인 오류가 발생했습니다.


8
그러나 무지한 개발자는 부가가치세 계산 규칙과 문서화 된 돈의 정밀한 한계를 무시했기 때문에 그렇게합니다.
TomTom

1
@TomTom 그러나이 데이터 유형의 오용 가능성에 대한 요점은 전혀 사용하지 않는 것에 대한 주장입니다.
Nathan Griffiths

@Nathan No. 나는 그것을 사용하지 않는 이유로서 주어진 주장은 기본적으로 무능한 개발자이므로 지적은 가짜입니다.
TomTom

1
@TomTom 슬프게도 많은 무능한 개발자 (그리고 많은 훌륭한 개발자)가 있으며,이 데이터가 미래에 어떻게 쿼리 될지 보장 할 수 없다면 아무도 여기에 설명 된 실수를 범하지 않을 것입니다. ,주의 측면에서 실수하고 10 진수 유형을 사용하는 것이 좋습니다. 즉,이 모든 대답을 읽은 후에는 돈이 사용하기에 가장 적합한 유형 인 특정 사용 사례가 있음을 알 수 있습니다. 매우 유용한 사용 사례가 없으면 사용하지 않을 것입니다 (예 : 열은 항상 대량의 재무 데이터를 대량로드하는 SUM으로 집계됩니다.
Nathan Griffiths

@TomTom은 정밀한 한계가 아닙니다. 내부 표현도 문제를 일으킬 수 있습니다. 돈은 무지한 개발자를 잡는 편리한 유형이며 개발자가 잘못 사용하는 훌륭한 유형은 아닙니다. vat 예제는 계산 규칙에 관계없이 무관 한 개발자가 일반에 적용 할 때 무섭지 않아야합니다.
제라드 ONeill

12

다른 답변의 일반적인 추력에 대한 반론으로. 참조 돈 ... 데이터 형식의 많은 혜택을! 관계형 엔진 에 대한 SQLCAT 안내서에서

특히 나는 다음을 지적 할 것이다.

고객 구현에서 돈 데이터 유형과 관련하여 흥미로운 성능 수치를 발견했습니다. 예를 들어 Analysis Services가 SQL Server money 데이터 형식과 일치하도록 통화 데이터 형식 (두 배)으로 설정되면 처리 속도 (행 / 초)가 13 % 향상되었습니다. SSIS 2008-세계 기록 ETL 성능에서 언급 한 것처럼 30 분 이내에 1.18TB를로드하는 SQL Server Integration Services (SSIS) 내에서 더 빠른 성능을 얻으려면 크기가 10 진수 (9,2) 인 열 4 개를 변경하는 것이 관찰되었습니다 TPC-H LINEITEM 테이블에서 5 바이트 (8 바이트)로 대량 삽입 속도가 20 % 개선되었습니다. 성능 향상의 이유는 SQL Server의 TDS (Tabular Data Stream) 프로토콜 때문입니다. 이는 데이터를 콤팩트 한 이진 형식으로 그리고 가능한 한 SQL Server의 내부 저장소 형식에 가까운 데이터를 전송하는 핵심 디자인 원칙을 가지고 있습니다. 경험적으로 이것은 Kernrate를 사용한 SSIS 2008 세계 기록 ETL 성능 테스트 중에 관찰되었습니다. 데이터 유형이 10 ​​진수에서 돈으로 전환 될 때 프로토콜이 크게 떨어졌습니다. 이것은 데이터 전송을 가능한 한 효율적으로 만듭니다. 복잡한 데이터 유형은 고정 너비 유형보다 처리하기 위해 추가 구문 분석 및 CPU주기가 필요합니다.

따라서 질문에 대한 대답은 "의존"입니다. 정밀도를 유지하기 위해 특정 산술 연산에 더주의를 기울여야하지만 성능 고려 사항으로 인해 가치가 있다는 것을 알 수 있습니다.


그러면 비트 코인 을 어떻게 저장 하시겠습니까?
Panagiotis Kanavos

@PanagiotisKanavos-나는 모른다. 나는 결코 비트 코인을 들여다 보지 않았으며 실제로 그것에 대해 아무것도 모른다!
Martin Smith

6

저는 제 자신의 전문 지식과 경험을 바탕으로 MONEY와 NUMERICAL에 대해 다른 견해를주고 싶습니다. 여기에서 제 관점은 MONEY입니다. 상당한 시간 동안 사용 해왔고 실제로는 NUMERICAL을 많이 사용하지 않았기 때문입니다 .. .

돈 프로 :

  • 기본 데이터 유형 . 이 기본 데이터 타입 (사용 정수 는 그래서 계산 불필요한 오버 헤드를 필요로하지 않도록하는 CPU 레지스터 (32 또는 64 비트)와 동일)를 작게 하고 빠른 ... MONEY 8 바이트를 필요 수치 (19 (4) )에는 9 바이트가 필요합니다 (12.5 % 더 큼) ...

    돈은 돈으로 사용되는 한 더 빠릅니다. 얼마나 빠릅니까? SUM백만 개의 데이터에 대한 간단한 테스트 결과 MONEY는 275ms, NUMERIC 517ms는 ... 거의 두 배 빠릅니다 . 왜 SUM 테스트입니까? 다음 Pro 포인트 참조

  • 돈을 위해 최고 . 돈은 돈을 저축하고 회계와 같은 운영에 가장 적합합니다. 단일 보고서는 SUM (수백만 개의 추가) 및 SUM 작업이 완료된 후 몇 번의 곱셈을 실행할 수 있습니다. 매우 큰 회계 응용 프로그램의 경우 거의 두 배 빠르며 매우 중요합니다 ...
  • 돈의 낮은 정밀도 . 실제 돈은 매우 정확할 필요는 없습니다. 내 말은, 많은 사람들이 약 1 센트의 USD를 걱정할 수 있지만, 약 0.01 센트의 USD는 어떻습니까? 실제로, 우리 나라에서는 은행이 더 이상 센트 (소수점 쉼표 뒤에있는 숫자)를 신경 쓰지 않습니다. 나는 미국 은행이나 다른 나라에 대해 모른다 ...

돈 사기 :

  • 한정된 정밀도 . MONEY는 쉼표 뒤에 4 자리의 자릿수 만 있으므로 나누기 등의 작업을 수행하기 전에 변환해야합니다. 그러나 다시 money정확하게 계산할 필요는없고 단지 돈이 아닌 번호...

그러나 ... 크지 만 여기에는 실제 돈과 관련된 응용 프로그램도 있지만 회계와 같은 많은 SUM 작업에는 사용하지 마십시오. 많은 나눗셈과 곱셈을 대신 사용하면 돈을 사용해서는 안됩니다 ...


1
돈이 십진수보다 빠르다고 말하는 경우 rdbms, 하드웨어, OS 실행, 특정 쿼리를 실행하는 특정 데이터와 같은 것들을 알려 주어야합니다. 또한, 그것이 완전히 정확하지 않다면, 세무 담당자는 나쁜 숫자를 돌려받는 것에 다소 불쾌감을 줄 것이기 때문에 재무 운영을하고 있지 않습니다. 예를 들어 미국 통화를 다루는 경우 천 센트를 걱정해야합니다. 돈이 그렇게하지 않으면 사용할 수 없습니다.
Haakon Løtveit

3
@ HaakonLøtveit이 전체 Q & A 스레드는 SQL Server 데이터 유형 "money"에 관한 것이므로 답변에 이것을 지정할 필요가 없다고 생각합니다. 일부 상황 (예 : 데이터로드)에서는 돈을 10 진수보다 빠르게 사용할 수 있습니다. 자세한 내용은 Martin Smith의 답변을 참조하십시오. 이 답변의 대다수에 동의합니다. Money를보다 10 진수보다 효율적으로 선택할 수있는 특정 사용 사례가 있지만 사용에 대한 매우 강력한 사례가 없다면 피해야한다고 생각합니다.
Nathan Griffiths

1
비트 코인은 소수점 이하 8 자리입니다. 당신은 심지어 money열에 저장할 수 없습니다
Panagiotis Kanavos

4

이전의 모든 게시물에는 유효한 포인트가 있지만 일부는 질문에 정확하게 답변하지 않습니다.

문제는 : 데이터 유형이 덜 정확하고 복잡한 계산에 사용될 경우 오류를 일으킬 수 있다는 것을 이미 알고있을 때 왜 돈을 선호 하는가?

복잡한 계산을하지 않고이 정밀도를 다른 요구에 맞출 수있을 때 돈을 사용합니다.

예를 들어, 계산할 필요가없고 유효한 통화 텍스트 문자열에서 데이터를 가져와야 할 때. 이 자동 변환은 MONEY 데이터 유형에서만 작동합니다.

SELECT CONVERT(MONEY, '$1,000.68')

나는 당신이 당신의 자신의 수입 루틴을 만들 수 있다는 것을 알고 있습니다. 그러나 전 세계 특정 로케일 형식으로 가져 오기 루틴을 다시 작성하지 않으려는 경우가 있습니다.

또 다른 예는 계산을 할 필요가없고 (값만 저장하면 됨) 1 바이트를 저장해야하는 경우 (돈은 8 바이트, 10 진수 (19,4)는 9 바이트) 방대한 양의 데이터를 읽는 것과 같은 일부 응용 프로그램 (빠른 CPU, 큰 RAM, 느린 IO)에서는이 속도도 더 빠를 수 있습니다.


2

가치에 대해 곱셈 / 나눗셈을해야 할 때 돈을 사용해서는 안됩니다. 돈은 정수가 저장되는 것과 같은 방식으로 저장되는 반면, 소수점은 소수점과 소수점으로 저장됩니다. 이것은 대부분의 경우 돈이 정확성을 떨어 뜨리는 반면, 10 진수는 원래의 규모로 다시 변환 할 때만 그렇게한다는 것을 의미합니다. 돈은 고정 소수점이므로 계산 중에 규모가 변경되지 않습니다. 그러나 10 진수 문자열로 인쇄 될 때 고정 소수점 (기본 2 문자열의 고정 위치가 아닌)이므로 최대 4까지의 값이 정확하게 표시됩니다. 덧셈과 뺄셈의 경우 돈이 좋습니다.

소수점은 내부적으로 10 진수로 표시되므로 소수점의 위치도 10 진수를 기준으로합니다. 이는 분수 부분이 돈과 마찬가지로 가치를 정확하게 나타내도록합니다. 차이점은 10 진수의 중간 값이 최대 38 자리의 정밀도를 유지할 수 있다는 것입니다.

부동 소수점 숫자를 사용하면 값이 정수인 것처럼 이진수로 저장되며 소수점 (또는 이진, ahem) 점의 위치는 숫자를 나타내는 비트를 기준으로합니다. 이진수는 소수점이므로 소수점 이하 10 진수는 정밀도를 잃습니다. 이 방법으로 1/5, 즉 0.2를 정확하게 표현할 수 없습니다. 돈이나 소수는이 한계를 겪지 않습니다.

돈을 십진수로 변환하고 계산을 수행 한 다음 결과 값을 돈 필드 또는 변수에 다시 저장하는 것이 쉽습니다.

POV에서 나는 숫자에 대해 너무 많은 생각을하지 않고도 발생하는 것들을 원합니다. 모든 계산이 십진수로 변환되면 나에게 십진수를 사용하고 싶습니다. 표시 목적으로 돈 필드를 저장합니다.

크기면에서 나는 내 마음을 바꿀만큼의 차이를 보지 못합니다. 돈은 4-8 바이트를 차지하지만 10 진수는 5, 9, 13 및 17이 될 수 있습니다. 9 바이트는 8 바이트 돈의 전체 범위를 포함 할 수 있습니다. 색인 방식 (비교 및 검색이 비슷해야 함)


공감 해 주셔서 감사합니다. 나는 이것을보고 있고 내가 말하려는 것을 얻었을 때, 또한 그것이 매우 혼란 스럽다는 것을 알 수 있습니다. 아마도 나는 비트 대 소수 예제로 나중에 다시 쓸 것입니다.
제라드 ONeill

2

정확한 주제에 돈보다 십진수를 사용하는 이유를 찾았습니다.

DECLARE @dOne   DECIMAL(19,4),
        @dThree DECIMAL(19,4),
        @mOne   MONEY,
        @mThree MONEY,
        @fOne   FLOAT,
        @fThree FLOAT

 SELECT @dOne   = 1,
        @dThree = 3,    
        @mOne   = 1,
        @mThree = 3,    
        @fOne   = 1,
        @fThree = 3

 SELECT (@dOne/@dThree)*@dThree AS DecimalResult,
        (@mOne/@mThree)*@mThree AS MoneyResult,
        (@fOne/@fThree)*@fThree AS FloatResult

10 진수 결과> 1.000000

MoneyResult> 0.9999

FloatResult> 1

그냥 테스트하고 결정하십시오.


2
우리는 당신의 결론 을 듣고 싶습니다 .
피터 Mortensen

@PeterMortensen Money와 Decimal 유형 사이의 완전성과 정확성을 원한다면 결정은 10 진법이어야한다고 생각합니다.
QMaster

1
위의 실제 결과로 답변을 업데이트하십시오. 그러면 여러분의 결론은 다음과 같이 읽는 사람에게 즉시 명백해질 것입니다 :-)
Agreax

1
@Ageax 결과가 답변에 추가되었습니다.
QMaster

1

방금이 블로그 항목을 보았습니다 : SQL Server의 Money vs. Decimal .

기본적으로 돈에 정밀도 문제가 있다고 말합니다 ...

declare @m money
declare @d decimal(9,2)

set @m = 19.34
set @d = 19.34

select (@m/1000)*1000
select (@d/1000)*1000

를 들어 money유형, 당신은 19.30 대신 19.34 얻을 것이다. 계산을 위해 돈을 1000 부분으로 나누는 응용 시나리오가 있는지 확실하지 않지만이 예제에서는 몇 가지 제한 사항이 있습니다.


15
"문제"가 아니라 "사양에 따라":« moneysmallmoney데이터 유형은 10 만분의 1 통화 단위까지 정확합니다.» msdn.microsoft.com/en-us/library/ms179882.aspx 에서 말했듯이 "쓰레기"라고 말하는 사람은 자신이 무엇을 말하는지 알 수 없습니다.
Albireo
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.