MySQL에서 10진수 필드 반올림 현상 막기
MySQL에서 DECIMAL 타입 컬럼에 소수점 이하 값을 저장할 때 값이 반올림되는 문제를 겪은 적이 있으신가요? 이는 DECIMAL 타입 선언 시 소수점 이하 자릿수(scale)를 지정하지 않았기 때문입니다. DECIMAL() 함수에 정밀도(precision)와 소수점 이하 자릿수를 함께 지정하면 반올림 없이 원래 값을 그대로 저장할 수 있습니다.
반올림이 발생하는 경우
먼저 반올림이 발생하는 예시 테이블을 만들어 보겠습니다. 아래와 같이 DECIMAL(7)로 컬럼을 선언하면 소수점 이하 자릿수가 0으로 설정됩니다.
mysql> create table stopRoundingDemo
-> (
-> Amount DECIMAL(7)
-> );
Query OK, 0 rows affected (0.67 sec)
insert 명령으로 몇 개의 레코드를 삽입해 보겠습니다.
mysql> insert into stopRoundingDemo values(7836.783);
Query OK, 1 row affected, 1 warning (0.43 sec)
mysql> insert into stopRoundingDemo values(1737.67);
Query OK, 1 row affected, 1 warning (0.23 sec)
mysql> insert into stopRoundingDemo values(110.50);
Query OK, 1 row affected, 1 warning (0.33 sec)
select 문으로 전체 레코드를 조회해 보겠습니다.
mysql> select *from stopRoundingDemo;
실행 결과는 다음과 같습니다.
+--------+
| Amount |
+--------+
| 7837 |
| 1738 |
| 111 |
+--------+
3 rows in set (0.08 sec)
위 출력 결과를 보면 소수점 이하 값이 모두 반올림된 것을 확인할 수 있습니다. 또한 데이터 삽입 시마다 경고(warning)가 발생했다는 점도 눈여겨볼 필요가 있습니다.
반올림 없이 소수점 값 그대로 저장하기
그렇다면 반올림을 막으려면 어떻게 해야 할까요? 해결 방법은 간단합니다. 새 테이블을 생성할 때 DECIMAL 타입에 정밀도와 소수점 이하 자릿수를 함께 지정하면 됩니다. 여기서는 DECIMAL(10,4)로 선언해 보겠습니다. 이는 총 10자리 숫자 중 소수점 이하 4자리까지 저장한다는 의미입니다.
mysql> create table stopRoundingDemo2
-> (
-> Amount DECIMAL(10,4)
-> );
Query OK, 0 rows affected (0.81 sec)
같은 방식으로 레코드를 삽입해 보겠습니다. 이번에는 경고가 발생하지 않습니다.
mysql> insert into stopRoundingDemo2 values(7836.783);
Query OK, 1 row affected (0.14 sec)
mysql> insert into stopRoundingDemo2 values(1737.67);
Query OK, 1 row affected (0.14 sec)
mysql> insert into stopRoundingDemo2 values(110.50);
Query OK, 1 row affected (0.16 sec)
select 문으로 데이터를 조회해 보겠습니다.
mysql> select *from stopRoundingDemo2;
실행 결과는 다음과 같습니다.
+-----------+
| Amount |
+-----------+
| 7836.7830 |
| 1737.6700 |
| 110.5000 |
+-----------+
3 rows in set (0.00 sec)
이제 소수점 이하 값이 반올림되지 않고 그대로 저장된 것을 확인할 수 있습니다. 지정한 소수점 이하 4자리만큼 부족한 자릿수는 0으로 채워져 표시됩니다.
정리
DECIMAL(M)처럼 정밀도만 지정하면 소수점 이하 자릿수는 기본값인 0이 되어 값이 반올림됩니다. 따라서 금액이나 측정값처럼 소수점 이하 데이터를 정확하게 저장해야 한다면 반드시 DECIMAL(M, D) 형태로 소수점 이하 자릿수(D)를 함께 지정해야 합니다.