십진수 열에 돈을 저장하는 것 - 어떤 정밀도와 규모입니까?
데이터베이스에 돈 값을 저장하기 위해 십진수 열을 사용하고 있는데, 오늘은 어떤 정밀도와 규모를 사용해야 할지 고민했습니다.
고정 너비의 문자 열이 더 효율적이기 때문에 십진수 열도 마찬가지일 수 있다고 생각했습니다.그런가요?
그리고 어떤 정밀도와 규모를 사용해야 합니까?저는 24시간 내내 정확하게 생각하고 있었습니다.과잉 살상인가요, 충분하지 않나요?
이것이 제가 하기로 결정한 것입니다.
- 변환 속도(해당되는 경우)를 트랜잭션 테이블 자체에 부동액으로 저장
- 계정 테이블에 통화 저장
- 거래 금액은 다음과 같습니다.
DECIMAL(19,4)
- 변환율을 사용하는 모든 계산은 내 애플리케이션에서 처리되므로 반올림 문제를 계속 제어할 수 있습니다.
전환율에 대한 변동 환율은 대부분 참고용이므로 문제가 되지 않을 것으로 생각하며, 어쨌든 소수점 이하로 캐스팅할 것입니다.
여러분의 소중한 의견에 감사드립니다.
이 모든 것에 저는 당프리즈찾있를고다면다만이니제, 저는합안신약이사다▁if니제,합-▁i안▁one'저▁a만▁for는▁suggest,-약▁aredsizeall를 추천합니다.DECIMAL(19, 4)
는 인기 있는 선택입니다(빠른 Google이 이를 증명합니다).첫 고정 소수점 VBA유형에서 합니다.Decimal
VB6/VBA6/Jet 4.0에서는 '버전 1.0' 스타일(즉, 완전히 구현되지 않음)로만 출시되었습니다.
고정 소수점 소수점 값을 저장하기 위한 경험칙은 반올림에 실제로 필요한 소수점 자리 수보다 적어도 하나 이상 더 저장하는 것입니다.오래된 것을 매핑하는 이유 중 하나.Currency
의 앞쪽 끝에 타이핑합니다.DECIMAL(19, 4)
뒤쪽 끝에 있는 타자는Currency
천성적으로 은행가들의 반올림을 전시한 반면,DECIMAL(p, s)
깎아서 둥글게 만든
대한 이하 :DECIMAL
공급업체의 기본값을 사용하는 대신 사용자 지정 반올림 알고리즘을 구현할 수 있습니다(그리고 은행가의 반올림은 최소한 .5로 끝나는 모든 값이 0에서 반올림될 것으로 예상하는 설계자에게는 놀라운 일입니다).
네.DECIMAL(24, 8)
제게는 과잉 살상으로 들리네요.대부분의 통화는 소수점 이하 네다섯 자리까지 따옴표로 묶습니다.나는 8(또는 그 이상)의 소수점 척도가 필요한 상황을 알고 있지만, 여기서 '정상' 통화량(예: 소수점 네 자리)이 비례하여 소수점 정밀도가 그에 따라 감소해야 한다는 것을 암시합니다(이러한 상황에서는 부동소수점 유형도 고려).그리고 요즘에는 소수 24의 정밀도를 요구할 만큼 많은 돈을 가진 사람은 없습니다 :)
그러나, 획일적인 접근 방식보다는 일부 연구가 적절할 수 있습니다.GAAP, EU 등 적용 가능한 회계 규칙에 대해서는 설계자 또는 도메인 전문가에게 문의하십시오. 이하인 규칙이 EU 내 국가 합니다. 나는 소 수 점 로 명 하 인 적 시 한 다 이 내 을 규 기 니 합 억 게 모 하 호 전 연 합 유 있 칙 럽 는 이 기 림 위 올 반 이 리 하 섯 자 다 ▁i ▁for ▁to 다 ▁explicit ▁rules ▁with ▁places 니 ▁recall ▁eu 합 ▁intra 나 ▁transfers ▁some 따라서 사용합니다.DECIMAL(p, 6)
네 하는 것 .회계사들은 일반적으로 소수점 이하 네 자리를 선호하는 것 같습니다.
Server의 PS SQL ServerMONEY
데이터 유형은 라운딩 시 정확도에 심각한 문제가 있기 때문에 휴대성 등을 고려해야 합니다.Aaron Bertrand의 블로그를 참조하십시오.
마이크로소프트와 언어 설계자들은 하드웨어 설계자들이 은행가의 반올림을 선택했기 때문에 [인용?]을 선택했습니다.예를 들어, 전기 전자 기술자 협회(IEEE) 표준에 명시되어 있습니다.하드웨어 설계자들은 수학자들이 선호하기 때문에 그것을 선택했습니다.위키백과를 참조하십시오.1906년 판의 확률과 오류 이론은 이것을 '컴퓨터의 규칙'("계산을 수행하는 인간을 의미하는 컴퓨터")이라고 불렀습니다.
우리는 최근 여러 통화로 가치를 처리하고 그 사이를 전환해야 하는 시스템을 구현했고, 어려운 몇 가지를 알아냈습니다.
돈을 벌기 위해 부동 소수점 번호를 사용하지 마십시오.
부동소수점 산술은 무언가를 망치기 전까지는 눈치채지 못할 수 있는 부정확성을 초래합니다.모든 값은 정수 또는 고정 소수점 유형으로 저장해야 하며, 고정 소수점 유형을 사용하도록 선택한 경우 해당 유형이 후드에서 수행하는 작업(즉, 내부적으로 정수 또는 부동 소수점 유형을 사용하는지 여부)을 정확히 이해해야 합니다.
계산 또는 변환을 수행해야 하는 경우:
- 값을 부동 소수점으로 변환
- 새 값 계산
- 숫자를 반올림하고 다시 정수로 변환
3단계에서 부동 소수점 번호를 정수로 다시 변환할 때, 단순히 캐스팅만 하지 말고 수학 함수를 사용하여 먼저 반올림합니다.일반적으로 다음과 같습니다.round
특별한 경우에는 그럴 수도 있지만,floor
또는ceil
차이점을 알고 신중하게 선택하세요.
숫자 유형을 값 옆에 저장
하나의 통화만 취급하는 경우에는 이 문제가 그다지 중요하지 않을 수 있지만, 여러 통화를 취급하는 경우에는 중요했습니다.USD, GBP, JPY, EUR 등의 통화에 대해 3자 코드를 사용했습니다.
상황에 따라 다음을 저장하는 것도 도움이 될 수 있습니다.
- 숫자가 세전인지 세후인지 여부(그리고 세율은 얼마였는가)
- 숫자가 변환의 결과인지 여부(및 변환된 값)
처리 중인 숫자의 정확도 한계 파악
실제 값의 경우 통화의 가장 작은 단위만큼 정확하려고 합니다.즉, 1센트, 1센트, 1엔, 1펜 등보다 작은 값이 없습니다.값을 이유 없이 정확도보다 높은 값으로 저장하지 마십시오.
내부적으로 더 작은 값을 처리하도록 선택할 수 있으며, 이 경우 다른 유형의 통화 값이 됩니다.코드가 어느 것이 어떤 것인지 알고 어떤 것이 혼동되지 않는지 확인합니다.여기서도 부동 소수점 값을 사용하지 않도록 합니다.
그 모든 규칙들을 합하여, 우리는 다음과 같은 규칙들을 결정했습니다.실행 코드에서 통화는 가장 작은 단위에 대한 정수를 사용하여 저장됩니다.
class Currency {
String code; // eg "USD"
int value; // eg 2500
boolean converted;
}
class Price {
Currency grossValue;
Currency netValue;
Tax taxRate;
}
데이터베이스에서 값은 다음 형식으로 문자열로 저장됩니다.
USD:2500
그것은 25달러의 가치를 저장합니다.통화를 다루는 코드가 데이터베이스 계층 자체 내에 있을 필요가 없기 때문에 모든 값이 먼저 메모리로 변환될 수 있습니다.다른 상황은 의심할 여지 없이 다른 해결책에 도움이 될 것입니다.
그리고 내가 아까 분명히 말하지 않았을 때를 대비해서, 플로트를 사용하지 마!
MySQL에서 돈을 다룰 때, 당신이 당신의 돈 가치의 정확성을 알고 있다면 DUBLE (13,2)을 사용하고, 당신이 단지 충분히 빠른 근사값을 원한다면 DOUBLE을 사용하세요.따라서 애플리케이션에서 최대 1조 달러(또는 유로 또는 파운드)의 비용 가치를 처리해야 하는 경우 다음과 같은 이점이 있습니다.
DECIMAL(13, 2)
또는 GAAP을 준수해야 하는 경우 다음을 사용합니다.
DECIMAL(13, 4)
SQL Server의 화폐 데이터 유형은 소수점 뒤에 네 자리가 있습니다.
SQL Server 2000 서적 온라인에서:
금전적 데이터는 긍정적이거나 부정적인 금액을 나타냅니다.Microsoft® SQL Server™ 2000에서는 화폐 데이터가 화폐 및 소액 화폐 데이터 유형을 사용하여 저장됩니다.화폐 데이터는 소수점 이하 네 자리까지 정확하게 저장할 수 있습니다.화폐 데이터 유형을 사용하여 -922,337,203,685,477.5808 - +922,337,203,685,477.5807 범위의 값을 저장합니다(값을 저장하려면 8바이트 필요).작은 돈 데이터 유형을 사용하여 -214,748.3648 ~ 214,748.3647 범위의 값을 저장합니다(값을 저장하려면 4바이트 필요).더 많은 소수 자릿수가 필요한 경우 대신 소수 데이터 유형을 사용합니다.
소수점 이하 4자리는 세계에서 가장 작은 통화 하위 통화를 저장할 수 있는 정확도를 제공합니다.소액결제(나노결제?!) 정확성이 필요한 경우 추가로 할인할 수 있습니다.
저도 선호합니다.DECIMAL
DBMS별 통화 유형의 경우 응용 프로그램 IMO에 이러한 종류의 논리를 더 안전하게 유지할 수 있습니다. 같은 줄에 있는 또 다른 접근 방식은 응용 프로그램 수준에서 사람이 읽기 쉽게 하기 위해 [long] 정수를 ¤unit.subunit로 포맷하는 것입니다(" = currency subunit"로 간단히 포맷하는 것입니다.
IBM Informix Dynamic Server를 사용하는 경우, 10진법 또는 숫자 유형의 마이너 변형인 MONEY 유형을 사용할 수 있습니다.이 유형은 항상 고정점 유형입니다(10진수는 부동 소수점 유형일 수 있음).1 ~ 32 범위의 척도와 0 ~ 32 범위의 정밀도를 지정할 수 있습니다(기본값은 척도 16 및 정밀도 2).따라서 저장해야 하는 항목에 따라 DECTIVE(16,2)를 사용할 수 있습니다. - 여전히 미국 연방 적자를 가장 가까운 센트까지 유지할 수 있습니다. - 또는 더 작은 범위 또는 소수 자릿수를 사용할 수 있습니다.
때때로 당신은 1센트 미만으로 갈 필요가 있을 것이고 매우 큰 데몬을 사용하는 국제 통화들이 있습니다.예를 들어, 고객에게 거래당 0.088센트를 청구할 수 있습니다.Oracle 데이터베이스에서 열은 NUMBER(20,4)로 정의됩니다.
만약 당신이 DB에서 어떤 종류의 산술 연산(청구율 곱셈 등)을 할 것이라면, 당신은 아마도 여기 사람들이 제안하는 것보다 훨씬 더 정확한 것을 원할 것입니다. 애플리케이션 코드에서 두 배의 정밀 부동 소수점 값 이하의 것을 절대 사용하고 싶지 않은 것과 같은 이유 때문입니다.
대부분의 경우 사용할 정밀도와 규모를 귀사나 귀사 고객의 요구사항에 따라 결정해야 한다고 생각합니다.예를 들어, 제가 일하고 있는 GBP로만 돈을 다루는 전자상거래 웹사이트의 경우, 저는 그것을 소수점(6, 2)으로 유지하도록 요구받았습니다.
답이 늦었지만, 제가 사용한 것은
DECIMAL(13,2)
99,999,999,999,999.99까지 허용해야 한다고 생각합니다.
언급URL : https://stackoverflow.com/questions/224462/storing-money-in-a-decimal-column-what-precision-and-scale
'programing' 카테고리의 다른 글
jquery를 사용하여 입력 필드의 특수 문자를 차단하거나 제한하려면 어떻게 해야 합니까? (0) | 2023.08.11 |
---|---|
관찰 가능한 RXJS 배열에 대한 단순 필터 (0) | 2023.08.11 |
선형 레이아웃 하위 항목 사이에 공백을 만드는 방법은 무엇입니까? (0) | 2023.08.11 |
PreferenceManager getDefaultSharedPreferences는 Android Q에서 더 이상 사용되지 않습니다. (0) | 2023.08.11 |
mysql 쿼리가 잘못된 인덱스를 사용합니다. (0) | 2023.08.11 |