PostgreSQL | 데이터 형식(Data type) | 숫자 형식(integer, decimal, double precision 등)


PosgtreSQL에서 사용할 수있는 데이터 타입에서 숫자 형식의 사용법에 대해 설명하도록 하겠다. 숫자는 정수 데이터 타입 (smallint, integer, bigint), 정밀한 숫자 (numeric, decimal), 부동 소수점 데이터 형 (real, double precision)이 포함되어 있다. 자동 증가 타입은 다음 페이지에서 설명한다.

정수 형식 (smallint, integer, bigint)

먼저 정수 데이터 형식이다. 취급 숫자의 범위가 다른 3 가지 데이터 타입이 있다.

형식 크기 범위 별칭
smallint 2 바이트 -32768에서 +32767 int2
integer 4 바이트 -2147483648에서 +2147483647 int, int4
bigint 8 바이트 -9223372036854775808에서 +9223372036854775807 int8

정수이므로 소수점이 있는 숫자는 처리 할 수 없다. 소수점이 있는 숫자를 저장하게 되면 정수로 변환되어 저장된다. 또한 각 데이터 타입에 저장할 수 있는 값의 범위가 정해져 있어 범위를 초과 한 값을 저장하려고 하면 오류가 발생한다.

예를 들어, 다음과 같은 테이블을 만들었다.

mydb=# create table numtest1 (num1 smallint, num2 integer, num3 bigint);
CREATE TABLE
mydb=#

각각의 컬럼에 설정되어 있는 데이터 형의 범위 내의 값이면 저장할 수 있다. 예를 들어, 다음과 같은 데이터를 저장한다.

mydb=# insert into numtest1 values (8000, 350000, 4000000000);
INSERT 0 1
mydb=#

범위를 초과하는 값을 저장하려고하면 오류가 발생한다. 예를 들어 num1 컬럼은 smallint 형이므로 저장할 수있는 값의 범위는 -32768에서 +32767까지이다. 이 값을 초과하여 50000을 값으로 저장하려고 한다.

mydb=# insert into numtest1 values (50000, 50000, 50000);
오류:  smallint1의 범위를 벗어났습니다.
mydb=#

num1 컬럼에 저장할 수있는 값의 범위를 초과 한 값을 저장하려고 하였기에 “오류: smallint의 범위를 벗어났습니다.“라는 오류가 발생하였다.

정밀한 숫자 (numeric, decimal)

다음은 정밀한 숫자이다.

타입 크기 특징 범위 별칭
numeric 가변 사용자 지정, 정확 소수점 위 131072 자리까지 소수점 아래는 16,383 자리까지 decimal

numeric 및 decimal 타입은 매우 큰 숫자를 저장할 수 있으며 연산을 해도 오차가 발생하고 정확하게 할 수 있는 데이터 타입이다. 그러나 처리는 정수와 부동 소수점 데이터 형과 비교해 매우 늦어 지므로 주의가 필요하다.

numeric 형을 지정하려면 다음 유형으로 한다.

NUMERIC(precision, scale) NUMERIC(precision) NUMERIC

precision는 숫자 전체의 최대 정확도, scale은 소수점 이하 자릿수를 지정한다. 예를 들어 numeric (5, 2)하면 소수점 이하 2자리, 전체 5자리 정확도의 값을 저장할 수 있기 때문에 저장할 수 있는 값의 범위는 -999.99에서 999.99가 된다.

scale을 생략하면 0이 지정된 것으로 간주된다. 또한 precision과 scale이 모두 생략된 경우는 가능한 최대의 정확도 및 소수점 이하의 자리수가 설정된다.

예를 들어, 다음과 같은 테이블을 만들었다.

mydb=# create table numtest2 (num numeric(5, 2));
CREATE TABLE
mydb=#

컬럼에 설정되어 있는 데이터 형의 범위 내의 값이면 저장할 수 있다. 예를 들어 다음과 같은 3개의 데이터를 저장한다.

mydb=# insert into numtest2 values (45), (34.25), (-752.4);
INSERT 0 3
mydb=#

정수 부분의 범위를 넘는 값을 저장하려고하면 오류가 발생한다. 예를 들어 num 컬럼은 numeric(5, 2) 형이므로 저장할 수 있는 값의 범위는 -999.99에서 +999.99까지이다. 이 값을 초과하는 1500.2 을 저장하려고 한다.

mydb=# insert into numtest2 values (1500.2);
오류:  수치 필드 오버플로우
상세정보:  전체 자릿수 5, 소수 자릿수 2의 필드는 10^3보다 작은 절대 값으로 반올림해야 합니다.
mydb=#

num 컬럼에 저장할 수있는 값의 범위를 초과 한 값을 저장하였기에 “오류: 수치 필드 오버플로우” 오류가 발생한다.

소수점 이하의 자리수가 지정한 범위를 초과하면 오류가 되지 않고 지정된 자릿수로 변환되어 저장된다. 예를 들어 다음과 같은 값을 2개 포함 해 보자.

mydb=# insert into numtest2 values (32.245),(-8.5224);
INSERT 0 2
mydb=# select * from numtest2;
   num
---------
   45.00
   34.25
 -752.40
   32.25
   -8.52
(5개 행)


mydb=#

32.245는 32.5로, -8.5224는 -8.52으로 저장되었다.

부동 소수점 데이터 타입 (real, double precision)

마지막으로 부동 소수점 데이터 형식이다. 취급 숫자의 범위가 서로 다른 두 가지 데이터 타입이 있다.

형식 크기 특징 범위 별칭
real 4 바이트 가변 정밀도, 부정확 최소 6 자리의 정밀도 (적어도 1E-37에서 1E + 37) float4
double precision 8 바이트 가변 정밀도, 부정확 최소 15 자리의 정밀도 (약 1E-307에서 1E + 308) float8

부동 소수점에서 저장하고 검색 할 때 오차가 발생할 수 있으므로 정확한 연산 등에는 적합하지 않다.

예를 들어, 다음과 같은 테이블을 만들었다.

mydb=# create table numtest3 (num1 real, num2 double precision);
CREATE TABLE
mydb=# 

컬럼에 설정되어 있는 데이터 형의 범위 내의 값이면 저장할 수 있다. 예를 들어, 다음과 같은 데이터를 저장한다.

mydb=# insert into numtest3 values (15.775, 812.5532245);
INSERT 0 1
mydb=# select * from numtest3;
   num1   |        num2
----------+--------------------
   15.775 |        812.5532245
(1개 행)


mydb=# 

각각의 데이터 형 이상의 자릿수의 값을 저장하려고하면 반올림 저장 될 수 있습니다. 예를 들어 다음과 같은 데이터를 저장한다.

mydb=# insert into numtest3 values (9.4475658, 52.75120024568652456);
INSERT 0 1
mydb=# select * from numtest3;
   num1   |        num2
----------+--------------------
   15.775 |        812.5532245
 9.447566 | 52.751200245686526
(2개 행)


mydb=# 

9.4475658는 9.44757으로 52.75120024568652456는 52.7512002456865으로 반올림되어 저장되었다.

범위를 초과하는 값을 저장하려고 하면 오류가 발생한다. 예를 들어 다음과 같은 값을 저장하려고 한다.

mydb=# insert into numtest3 values (4.8e50, 4.8e50);
오류:  "480000000000000000000000000000000000000000000000000"는 real 자료형의 범위를 벗어납니다.
mydb=#

저장할 수 있는 값의 범위를 초과 한 값을 저장하려고했기에 범위에 벗어났다는 오류가 발생되었다.

PosgtreSQL에서 사용할 수있는 데이터 형식에서 숫자 형식의 사용법에 대해 설명하였다.