SQL Server에서 MONEY 또는 DECIMAL (x, y) 데이터 유형을 선택해야합니까?
money
데이터 유형과 같은 것 decimal(19,4)
(돈이 내부적으로 사용하는 것) 사이에 실제 차이가 있는지 궁금합니다 .
money
SQL Server에만 해당되는 것으로 알고 있습니다. 하나를 선택해야 할 강력한 이유가 있는지 알고 싶습니다. 대부분의 SQL Server 샘플 (예 : AdventureWorks 데이터베이스) 은 가격 정보와 같은 용도로 사용 money
되지 않습니다 decimal
.
money 데이터 유형을 계속 사용해야합니까, 아니면 십진수를 사용하면 이점이 있습니까? 돈은 입력하는 문자 수가 적지 만 유효한 이유는 아닙니다. :)
절대 돈을 사용해서는 안됩니다. 그것은 정확하지 않으며 순수한 쓰레기입니다. 항상 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
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 자리가 필요하지 않은 한 좋으며, 돈을 나타내지 않는 스칼라가 decimal
s 인지 확인하십시오 .
무엇을하고 있는지 모른다면 모든 것이 위험합니다
고정밀 소수 유형조차도 하루를 저장할 수 없습니다.
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
유형은 정수
의 텍스트 표현 smallmoney
과 decimal(10,4)
비슷하게 보일 수 있지만, 그들이 상호 교환하지 않습니다. 날짜가 저장된 것으로 보았을 때 울부 짖 varchar(10)
습니까? 이것은 같은 것입니다.
뒤에서 money
/ smallmoney
는 단지 bigint
/ int
입니다. 텍스트 표현의 소수점 money
은 yyyy-mm-dd 날짜의 대시와 마찬가지로 시각적 솜털입니다. SQL은 실제로 내부적으로 저장하지 않습니다.
decimal
vs money
와 관련 하여 필요에 맞는 것을 선택하십시오. money
유닛의 1 / 10,000번째의 정수배로서 차지하는 값을 저장하는 것은 매우 일반적이므로 유형이 존재한다. 또한 단순한 덧셈과 뺄셈을 넘어 실제 돈과 계산을 다루는 경우 데이터베이스 수준에서 그렇게해서는 안됩니다! Banker 's Rounding (IEEE 754) 을 지원하는 라이브러리를 사용하여 애플리케이션 레벨에서 수행하십시오.
WayneM은 돈이 SQL Server에만 해당된다는 것을 알고 있다고 언급했습니다. 그러나 그는 십진수 이상의 돈을 사용해야하는 이유가 있는지 묻고 있으며 그 반대의 경우도 여전히 분명한 이유 중 하나는 여전히 언급해야한다고 생각합니다. 십진수를 사용한다는 것은 DBMS를 변경해야 할 경우 걱정할 필요가 덜한 것을 의미합니다 -일어날 수 있습니다.
시스템을 최대한 유연하게 만드십시오!
글쎄, 난 좋아 MONEY
! 이보다 바이트가 저렴 DECIMAL
하고 (커버 아래) 더하기 및 빼기 연산은 본질적으로 정수 연산이므로 계산이 더 빠르게 수행됩니다. 알지 못하는 사람들에게 큰 경고 인 INT
@SQLMenace 의 예제는 예가 될 수있는 egers 에게 동일하게 적용될 수 있습니다. 그러나 적절한 경우 정수를 사용하지 않는 이유는 없습니다 .
따라서 완벽하게 '안전'하고 MONEY
다루는 것이 MONEY
사용하는 것이 적절하고 수학적 규칙에 따라 사용하는 것이 적절합니다 ( INT
에거 와 동일 ).
SQL Server MONEY
가 DECIMAL
s ( 들)로 나누기와 곱셈을 장려하면 더 좋았을 FLOAT
것입니다. 그러나 그들은 이것을 선택하지 않았습니다. 또한 INT
예를 FLOAT
나누는 사람들 을 홍보하도록 선택하지 않았습니다 .
MONEY
정밀도 문제가 없습니다. DECIMAL
계산 중에 사용되는 더 큰 중간 유형을 얻는 것은 그 유형을 사용하는 '기능'일뿐입니다 (실제로 '기능'이 얼마나 멀리 확장되는지 확실하지 않습니다).
구체적인 질문에 답하기 위해 "추천 이유"? 당신은 절대 최대 성능을 원한다면 음, SUM(x)
어디 x
수 중 수 DECIMAL
또는 MONEY
다음 MONEY
가장자리를해야합니다.
또한 크기가 SMALLMONEY
4 바이트에 불과한 작은 사촌이라는 사실을 잊지 마십시오. 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
-정수와 동일).
다른 답변의 일반적인 추력에 대한 반론으로. 참조 돈 ... 데이터 형식의 많은 혜택을! 관계형 엔진 에 대한 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주기가 필요합니다.
따라서 질문에 대한 대답은 "의존"입니다. 정밀도를 유지하기 위해 특정 산술 연산에 대해 더주의해야하지만 성능 고려 사항이이를 가치있게 만들 수 있습니다.
우리는 방금 비슷한 문제를 겪었고 최상위 프레젠테이션을 제외하고는 Money를 사용하지 않는 것에 대해 +1이되었습니다. 우리는 여러 가지 테이블 (효과적으로 판매 바우처 및 판매 송장)을 가지고 있으며 각 테이블에는 역사적 이유로 하나 이상의 Money 필드가 포함되어 있으며, 총 송장 세금 중 각 세금과 얼마나 관련이 있는지 계산하기 위해 비례 계산을 수행해야합니다. 판매 바우처의 라인. 우리의 계산은
vat proportion = total invoice vat x (voucher line value / total invoice value)
이로 인해 실제 돈 / 돈 계산으로 인해 분할 부분에서 스케일 오류가 발생하여 잘못된 vat 비율로 곱해집니다. 이 값이 추가되면 총 송장 값에 합산되지 않는 VAT 비율의 합계가됩니다. 괄호 안의 값 중 하나가 10 진수 (내가 그중 하나를 캐스트하려고 함) 인 경우 vat 비율이 정확합니다.
대괄호가 원래 작동하지 않았을 때 관련된 큰 값 때문에 효과적으로 더 큰 스케일을 시뮬레이션하고 있다고 생각합니다. 우리는 곱셈을 먼저 수행했기 때문에 대괄호를 추가했습니다. 드물게 계산에 사용할 수있는 정밀도를 날려 버렸지 만 이제는 훨씬 더 일반적인 오류가 발생했습니다.
저는 제 자신의 전문 지식과 경험을 바탕으로 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 작업에는 사용하지 마십시오. 많은 나눗셈과 곱셈을 대신 사용하면 돈을 사용해서는 안됩니다 ...
가치에 대해 곱셈 / 나눗셈을해야 할 때 돈을 사용해서는 안됩니다. 돈은 정수가 저장되는 것과 같은 방식으로 저장되는 반면, 소수점은 소수점과 소수점으로 저장됩니다. 이것은 대부분의 경우 돈이 정확성을 떨어 뜨리는 반면, 소수는 원래의 규모로 다시 변환 할 때만 돈이 줄어드는 것을 의미합니다. 돈은 고정 소수점이므로 계산 중에 규모가 변경되지 않습니다. 그러나 10 진수 문자열로 인쇄 될 때 고정 소수점 (기본 2 문자열의 고정 위치와 반대)이므로 최대 4까지의 값이 정확하게 표시됩니다. 덧셈과 뺄셈의 경우 돈이 좋습니다.
소수점은 내부적으로 10 진수로 표시되므로 소수점의 위치도 10 진수를 기준으로합니다. 이는 분수 부분이 돈과 마찬가지로 가치를 정확하게 나타내도록합니다. 차이점은 10 진수의 중간 값이 최대 38 자리의 정밀도를 유지할 수 있다는 것입니다.
부동 소수점 숫자를 사용하면 값이 정수인 것처럼 이진수로 저장되며 소수점 (또는 이진, ahem) 점의 위치는 숫자를 나타내는 비트를 기준으로합니다. 이진수는 소수점이므로 소수점 이하 10 진수는 정밀도를 잃습니다. 이 방법으로 1/5, 즉 0.2를 정확하게 표현할 수 없습니다. 돈이나 소수는이 한계를 겪지 않습니다.
돈을 십진수로 변환하고 계산을 수행 한 다음 결과 값을 돈 필드 또는 변수에 다시 저장하는 것이 쉽습니다.
POV에서 나는 숫자에 대해 너무 많은 생각을하지 않고도 발생하는 것들을 원합니다. 모든 계산이 십진수로 변환되면 나에게 십진수를 사용하고 싶습니다. 표시 목적으로 돈 필드를 저장합니다.
크기면에서 나는 내 마음을 바꿀만큼의 차이를 보지 못합니다. 돈은 4-8 바이트를 차지하지만 10 진수는 5, 9, 13 및 17이 될 수 있습니다. 9 바이트는 8 바이트의 돈이 할 수있는 전체 범위를 포괄 할 수 있습니다. 색인 방식 (비교 및 검색이 비슷해야 함)
이전의 모든 게시물에는 유효한 포인트가 있지만 일부는 질문에 정확하게 답변하지 않습니다.
문제는 : 데이터 유형이 덜 정확하고 복잡한 계산에 사용될 경우 오류를 일으킬 수 있다는 것을 이미 알고있을 때 왜 돈을 선호 하는가?
복잡한 계산을하지 않고이 정밀도를 다른 요구에 맞출 수있을 때 돈을 사용합니다.
예를 들어, 계산할 필요가없고 유효한 통화 텍스트 문자열에서 데이터를 가져와야 할 때. 이 자동 변환은 MONEY 데이터 유형에서만 작동합니다.
SELECT CONVERT(MONEY, '$1,000.68')
나는 당신이 당신 자신의 수입 루틴을 만들 수 있다는 것을 알고 있습니다. 그러나 전 세계 특정 로케일 형식으로 가져 오기 루틴을 다시 작성하지 않으려는 경우가 있습니다.
또 다른 예는 계산을 할 필요가없고 (값만 저장하면 됨) 1 바이트를 저장해야하는 경우 (돈은 8 바이트, 10 진수 (19,4)는 9 바이트) 방대한 양의 데이터를 읽는 것과 같은 일부 응용 프로그램 (빠른 CPU, 큰 RAM, 느린 IO)에서는이 속도도 더 빠를 수 있습니다.
방금이 블로그 항목을 보았습니다 : 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 부분으로 나누는 응용 시나리오가 있는지 확실하지 않지만이 예제에서는 몇 가지 제한 사항이 있습니다.
정확한 주제에 돈보다 십진수를 사용하는 이유를 찾았습니다.
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
그냥 테스트하고 결정하십시오.
'Programming' 카테고리의 다른 글
IPv6 주소의 텍스트 표현의 최대 길이는? (0) | 2020.02.20 |
---|---|
Android에서 프로그래밍 방식으로 앱 언어 변경 (0) | 2020.02.20 |
.NET의 문자열에서 분음 부호 (악센트)를 어떻게 제거합니까? (0) | 2020.02.20 |
CSS에 패딩이있을 때 넘치지 않고 TextArea를 100 % 너비로 만들려면 어떻게합니까? (0) | 2020.02.20 |
Fragments에서 onBackPressed ()를 구현하는 방법은 무엇입니까? (0) | 2020.02.20 |