고동의 데이터 분석

[개념] 아주 간단한 SQL 정수형 이야기 (int, bigint)

by 소라고동_

SQL 에서 숫자형 데이터를 다룰 때 알아두면 좋을 내용을 간략히 담아본 포스팅입니다.


0. 궁금함의 계기

오늘 회사에서 후임분이 저에게 숫자형과 관련해서 도움을 요청했는데요.

상황
- 후임분이 sql 쿼리로 추출한 데이터를 csv 파일로 다운받은 뒤, 개발팀에 전달
- 개발팀에서는 숫자 뒤에 소숫점(.0) 이 붙어있는 문제 때문에 오류가 나는 이유로 정수형으로 수정 요청

문제는 Zeppelin 에서 sql 로 추출했을 땐 소숫점이 보이지 않았고, 다운받은 csv 파일에서도 소숫점이 보이지 않았다는 것입니다.

즉, 숫자형의 문제 때문에 이 상황이 생겼다는 것을 인지하기가 어려웠다는 것이죠.

 

그래서 저는 단순히 '실수형을 정수형으로 바꿔드리면 될거에요~' 라고 이야기 한 뒤 직접 잘 되는지 test 를 해봤습니다.

그러고는 int 에 대한 문제를 발견했고, 예전부터 이 문제 때문에 int 를 잘 사용하지 않았던 기억이 떠올랐습니다.

이 이유를 제대로 알기 위해서 정수형에 대해 찾아보게 되었습니다.

 

 

 

1. int 를 사용했을때의 문제점

test 를 위해서 아무 값이나 집계를 해보고 값이 잘 표현이 되는지를 확인해봤습니다.

그런데 실수형(Double)과 정수형(Int)의 값이 다른 것을 확인할 수 있었습니다.

이렇게 말이죠. 

select Key
    , sum(column_a) double_a
    , sum(column_b) double_b
    
    , int(sum(column_a)) sum_int_a
    , int(sum(column_b)) sum_int_b
    
from example
where key = 131125
group by 1

숫자가 작은 경우에는 똑같이 9,704 라는 값이 나왔는데, 큰 값의 경우 좀 다른 것을 확인할 수 있습니다.

왜 그럴까? 라는 생각을 하며 쿼리를 조금 수정해봤습니다.

 

select Key
    , sum(column_a) double_a
    , sum(column_b) double_b
    
    , int(sum(column_a)) sum_int_a
    , int(sum(column_b)) sum_int_b
    
    , sum(int(column_a)) int_sum_a
    , sum(int(column_b)) int_sum_b
    
from example
where key = 131125
group by 1

각 값을 int 로 바꿔준 뒤 집계를 했을 땐 값이 제대로 표현되었습니다.

뭐가 문제였을까요??

 

 

2. 문제가 발생한 이유

이유는 int 가 표현할 수 있는 정수의 범위가 제한적이었기 때문입니다.

참고한 게시글은 아래에 있으니 한 번 확인해보시길 바랍니다 (숫자형에 대해서 잘 설명해놓은 글인 것 같습니다.)

 

MySQL 최적의 데이터 타입 선택 방법 - Useful Guide

MySQL 최적의 데이터 타입 선택 방법, 정수, 실수, 문자열, 날짜, 시간, 비트(Bit), numeric, char, varchar, decimal, double, blob, text, integer, MySQL 타입 종

nomadlee.com

 

위 글에서 우리가 필요한 부분만 간단히 살펴보면 이렇습니다.

데이터 타입 표현 가능한 정수 범위
int 2,147,483,647
bigint 9,223,372,036,854,775,807

즉, int 형은 2,147,483,647 이 넘어가는 실수형 숫자를 정수형으로 바꿀 때 모두 2,147,483,647 로 만들어버린다는 것입니다.

그래서 처음 int(집계된 값) 을 보면 2,147,483,647 라고 표현되어있음을 확인할 수 있습니다.

수정한 SQL 쿼리에서는 모든 값을 int 로 바꾼 뒤 집계를 해줬기 때문에 문제가 발생하지 않았던 것입니다.

 

 

3. 해결책

1) 숫자형 데이터를 먼저 int 로 바꾼 다음 집계한다.

쿼리로 보면 이렇게 표현이 됩니다.

select Key
    , sum(int(column_a)) int_sum_a
    , sum(int(column_b)) int_sum_b
    
from example
where key = 131125
group by 1

이 경우에는 문제가 되지 않는 것 처럼 보이지만, 늘 그런 것은 아닙니다.

만약 집계하기 전의 값이 2,147,483,647 이 넘어가는 경우가 존재한다면 값이 소실되는 문제가 발생합니다.

그렇기 때문에 숫자 값이 큰 데이터를 다루는 경우라면 int 가 아닌 bigint 를 사용하는 것이 좋습니다.

 

2) bigint 활용하기

bigint 는 9,223,372,036,854,775,807 까지 표현이 가능하다고 합니다.

그렇기 때문에 집계가 된 값을 정수형으로 바꿔주든, 정수형으로 바꾼 뒤 집계를 하든 상관 없이 값이 제대로 표현이 됩니다.

(집계 전의 값이 9,223,372,036,854,775,807 이하라면 말이죠.)

SQL 에서 확인을 해보면 아래와 같습니다.

select Key
    , sum(bigint(column_a)) bigint_sum_a
    , sum(bigint(column_b)) bigint_sum_b
    
    , bigint(sum(column_a)) bigint_a
    , bigint(sum(column_b)) bigint_b
    
from example
where key = 131125
group by 1

 

이렇게 하면 값들이 잘 표현된다는 것을 확인할 수 있습니다.

 

 

4. 결론

실수형 숫자 데이터를 정수형으로 바꿀 땐 마음 편하게 bigint 를 사용하자

 

 

끝.

'#4. 소소한 개념 노트' 카테고리의 다른 글

[개념] Hue 권한 설정에 대하여  (2) 2022.03.24

블로그의 정보

고동의 데이터 분석

소라고동_

활동하기