문제

저는 소수판을 사용하여 데이터베이스에 돈 값을 저장하고 있으며 오늘은 어떤 정밀도와 규모를 사용할 것인지 궁금했습니다.

아마도 고정 너비의 숯 열이 더 효율적이기 때문에, 나는 소수점 열에 대해서도 마찬가지라고 생각했습니다. 그게?

그리고 어떤 정밀도와 규모를 사용해야합니까? 나는 정밀도 24/8을 생각하고 있었다. 그 과잉은 충분하지 않습니까?


이것이 제가 결정한 것입니다.

  • 트랜잭션 테이블 자체에 전환율 (해당되는 경우)을 플로트로 저장하십시오.
  • 계정 테이블에 통화를 저장하십시오
  • 거래 금액은 a DECIMAL(19,4)
  • 전환율을 사용한 모든 계산은 응용 프로그램에 의해 처리되므로 반올림 문제를 제어합니다.

전환율에 대한 플로트가 문제라고 생각하지 않습니다. 대부분 참조 용이기 때문에 어쨌든 소수점으로 캐스팅 할 것입니다.

귀중한 의견에 감사드립니다.

도움이 되었습니까?

해결책

한 가지 크기에 맞는 것을 찾고 있다면 DECIMAL(19, 4) 인기있는 선택입니다 (빠른 Google은 이것을 설명합니다). 나는 이것이 이전 VBA/Access/Jet 통화 데이터 유형에서 비롯된 것으로 생각하며, 언어의 첫 번째 고정점 소수점 유형입니다. Decimal VB6/VBA6/JET 4.0에서 '버전 1.0'스타일 (즉, 완전히 구현되지 않음)으로 만 나왔습니다.

경험의 규칙 저장 고정 지점의 소수점 값은 실제로 반올림을 허용하는 데 필요한 것보다 최소한 10 진수를 저장하는 것입니다. 기존을 매핑하는 이유 중 하나입니다 Currency 앞쪽 끝에 입력하십시오 DECIMAL(19, 4) 백엔드의 유형은 그게되었습니다 Currency 자연별로 은행가의 반올림을 보여주었습니다 DECIMAL(p, s) 잘림으로 반올림.

저장에 추가로 소수점이 있습니다 DECIMAL 공급 업체의 기본값을 가져 오지 않고 사용자 정의 반올림 알고리즘을 구현할 수 있습니다 (및 은행가의 반올림은 최소한으로 말하면, .5로 끝나는 모든 값이 0에서 끝나는 모든 값을 기대하는 디자이너에게는 최소한 말을합니다).

예, DECIMAL(24, 8) 나에게 과도한 것처럼 들린다. 대부분의 통화는 소수점 이하 5 개 자리로 인용됩니다. 나는 10 진수 규모가 8 (또는 그 이상)의 상황을 알고 있습니다. ~이다 필요하지만 이것은 '정상적인'금전적 금액 (예 : 소수점 이하 자리)이 진행된 곳으로, 소수 정밀도가 그에 따라 감소되어야한다는 것을 암시합니다 (또한 그러한 상황에서 부동 소수점 유형을 고려). 그리고 요즘에는 24의 소수 정밀도를 요구하기 위해 많은 돈을 가지고 있지 않습니다. :)

그러나 하나의 크기에 맞는 접근 방식이 아니라 일부 연구가 순서대로있을 수 있습니다. GAAP, EU 등에 적용 할 수있는 회계 규칙에 대해 설계자 또는 도메인 전문가에게 문의하십시오. 저는 소수점 이하 5 곳으로 반올림하기위한 명시 적 규칙이있는 EU 내내 전송을 모호하게 기억합니다. DECIMAL(p, 6) 저장 용. 회계사는 일반적으로 4 자리 자리를 선호하는 것 같습니다.


추신 : SQL Server를 피하십시오 MONEY 데이터 유형은 반올림 할 때 정확성에 심각한 문제가 있기 때문에 휴대 성 등과 같은 고려 사항을 참조하십시오. Aaron Bertrand의 블로그.


하드웨어 디자이너가 그것을 선택했기 때문에 Microsoft 및 Language Designers는 Banker의 반올림을 선택했습니다. 예를 들어 IEEE (Institute of Electrical and Electronics Engineers) 표준에 포함되어 있습니다. 그리고 하드웨어 디자이너는 수학자들이 그것을 선호하기 때문에 그것을 선택했습니다. 보다 위키 백과; Paraphrase : 1906 년 확률과 오류 이론의 판은 이것을 '컴퓨터의 규칙'이라고 불렀습니다 ( "컴퓨터"는 계산을 수행하는 인간을 의미합니다).

다른 팁

우리는 최근에 여러 통화로 값을 처리하고 그 사이를 전환 해야하는 시스템을 구현하고 몇 가지 어려운 방법을 알아 냈습니다.

돈을 위해 부동 소수점 번호를 사용하지 마십시오

플로팅 포인트 산술은 무언가를 망칠 때까지 눈치 채지 못할 수있는 부정확성을 소개합니다. 모든 값은 정수 또는 고정 시세 유형으로 저장되어야하며 고정 시세 유형을 사용하기로 선택한 경우 해당 유형이 후드 아래에서 수행하는 작업을 정확하게 이해해야합니다 (즉, 내부적으로 정수 또는 부동 소수점을 사용합니까? 유형).

계산 또는 변환을 수행 해야하는 경우 :

  1. 값을 플로팅 포인트로 변환합니다
  2. 새로운 가치를 계산합니다
  3. 번호를 반올림하여 정수로 다시 변환

3 단계에서 플로팅 포인트 번호를 정수로 다시 변환 할 때는 캐스트하지 마십시오. 수학 기능을 사용하여 먼저 반올림하십시오. 이것은 일반적으로 될 것입니다 round, 특별한 경우에는 그럴 수 있습니다 floor 또는 ceil. 차이점을 알고 조심스럽게 선택하십시오.

값과 함께 숫자 유형을 저장하십시오

하나의 통화 만 처리하는 경우에는 중요하지 않을 수 있지만 여러 통화를 처리하는 데 중요했습니다. 우리는 USD, GBP, JPY, EUR 등과 같은 통화에 대한 3 자 코드를 사용했습니다.

상황에 따라 저장하는 것이 도움이 될 수 있습니다.

  • 수가 세금 전후에 있는지 여부 (및 세율은 무엇인지)
  • 숫자가 변환의 결과인지 여부 (및 그것이 변환 된 것)

당신이 다루는 숫자의 정확도 범위를 알고 있습니다.

실제 가치의 경우 통화의 가장 작은 단위만큼 정확 해지고 싶습니다. 이것은 당신이 센트보다 작은 값, 페니, 엔, 펜 등을 의미합니다.

내부적으로, 당신은 작은 값을 다루기로 선택할 수 있습니다. 다른 유형의 통화 값. 코드가 어느 것이 무엇인지 알고 있는지 확인하고 혼합하지 않도록하십시오. 여기에서도 부동 소수점 값을 사용하지 마십시오.


이 모든 규칙을 함께 추가하면 다음 규칙을 결정했습니다. 실행 코드에서 통화는 가장 작은 장치의 정수를 사용하여 저장됩니다.

class Currency {
   String code;       //  eg "USD"
   int value;         //  eg 2500
   boolean converted;
}

class Price {
   Currency grossValue;
   Currency netValue;
   Tax taxRate;
}

데이터베이스에서 값은 다음 형식의 문자열로 저장됩니다.

USD:2500

그것은 $ 25.00의 가치를 저장합니다. 통화를 다루는 코드가 데이터베이스 계층 자체 내에있을 필요가 없으므로 모든 값을 먼저 메모리로 변환 할 수 있기 때문에 그렇게 할 수있었습니다. 다른 상황은 의심 할 여지없이 다른 솔루션에 적합 할 것입니다.


그리고 내가 더 일찍 그것을 명확하게하지 않았다면 float를 사용하지 마십시오!

MySQL에서 돈을 처리 할 때는 돈 값의 정밀도를 알고 있거나 빠른 좋은 대략적인 값을 원한다면 Deboud를 사용하는 경우 Decimal (13,2)을 사용하십시오. 따라서 응용 프로그램이 최대 1 조 달러 (또는 유로 또는 파운드)까지 돈 가치를 처리 해야하는 경우 다음과 같습니다.

DECIMAL(13, 2)

또는 준수 해야하는 경우 GAAP 그런 다음 사용하십시오 :

DECIMAL(13, 4)

소수점 이하 4 자리는 세계에서 가장 작은 통화 하위 유닛을 보관할 수있는 정확성을 제공합니다. 미세 송금 (나노 페이먼트?!) 정확도가 필요한 경우 더 아래로 내릴 수 있습니다.

나도 선호합니다 DECIMAL DBMS 특이 적 돈 유형을 위해서는 응용 프로그램 IMO에 그런 종류의 논리를 유지합니다. 같은 선을 따라 다른 접근법은 단순히 [Long] 정수를 사용하는 것입니다. 인간의 가독성 (¤ = 통화 기호)을 위해 ¤unit.subunit로 형식화되는 것이 응용 프로그램 수준에서 수행되는 것입니다.

SQL Server의 Money DataType은 10 진수 후 4 자리가 있습니다.

SQL Server 2000 Books Online에서 :

금전적 데이터는 긍정적 또는 부정적인 금액의 돈을 나타냅니다. Microsoft® SQL Server ™ 2000에서 금전적 데이터는 Money 및 Smallmoney 데이터 유형을 사용하여 저장됩니다. 금전적 데이터는 소수점 이하의 정확도로 저장 될 수 있습니다. 돈 데이터 유형을 사용하여 -922,337,203,203,477.5808 ~ +922,337,203,685,477.5807 (값을 저장하려면 8 바이트가 필요함) 범위의 값을 저장하십시오. SmallMoney 데이터 유형을 사용하여 -214,748.3648에서 214,748.3647의 범위에 값을 저장하십시오 (값을 저장하려면 4 바이트가 필요함). 더 많은 소수 자리가 필요한 경우, 십진수 데이터 유형을 대신 사용하십시오.

때로는 1 센트 미만으로 가야하며 매우 큰 악마를 사용하는 국제 통화가 있습니다. 예를 들어, 거래 당 고객에게 0.088 센트를 청구 할 수 있습니다. 내 Oracle 데이터베이스에서 열은 숫자 (20,4)로 정의됩니다.

DB에서 어떤 종류의 산술 작업을 수행하려고한다면 (청구 속도를 곱 등), 여기 사람들이 제안하는 것보다 훨씬 더 많은 정밀도를 원할 것입니다. 애플리케이션 코드에서 이중 프레시션 플로팅 포인트 값보다 적은 것을 사용하려고합니다.

IBM Informix Dynamic Server를 사용하는 경우 소수점 또는 숫자 유형의 작은 변형 인 돈 유형이 있습니다. 항상 고정점 유형입니다 (소수점은 부동 소수점 유형 일 수 있음). 1에서 32 사이의 스케일, 0에서 32 사이의 정밀도를 지정할 수 있습니다 (기본값은 16, 정밀도 2). 따라서 저장해야 할 사항에 따라 미국 연방 적자, 가장 가까운 센트까지 여전히 큰 소수 (16,2)를 사용할 수 있습니다.

많은 부분에서 귀하 또는 귀하의 고객의 요구 사항은 사용할 정밀도와 규모를 지시해야한다고 생각합니다. 예를 들어, 전자 상거래 웹 사이트의 경우 GBP로만 돈을 다루는 작업을 수행하고 있으며 소수점으로 유지해야했습니다 (6, 2).

여기서 늦은 답변이지만 사용했습니다

DECIMAL(13,2)

내가 생각하는 것은 최대 99,999,999,999.99를 허용해야합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top