숫자 데이터 타입

숫자 데이터 타입 (Numeric data types)

이 주제는 Snowflake에서 지원하는 숫자 데이터 타입과, 숫자 상수·리터럴에 지원되는 포맷을 설명해요. 고정 소수점 타입(NUMBER, DECIMAL 등)과 부동 소수점 타입(FLOAT, DOUBLE, DECFLOAT 등)으로 나뉘며, 각 타입의 정밀도·스케일·저장 방식·특수 값까지 다뤄요. 실무에서 가장 많이 쓰는 타입이라 정확히 이해하는 게 중요해요.

출처: Snowflake SQL Reference

본문

이 주제는 Snowflake에서 지원하는 숫자 데이터 타입과, 숫자 상수·리터럴에 지원되는 포맷을 설명해요.

고정 소수점(fixed-point) 숫자 데이터 타입

Snowflake는 고정 소수점 숫자에 다음 데이터 타입을 지원해요.

NUMBER

선택적인 정밀도(precision)와 스케일(scale)을 가진 최대 38자리 숫자:

  • 정밀도(Precision): 허용되는 총 자릿수.
  • 스케일(Scale): 소수점 오른쪽에 허용되는 자릿수.

기본적으로 정밀도는 38, 스케일은 0이에요. 즉 NUMBER(38, 0)이죠. 정밀도는 주어진 타입의 컬럼에 삽입되거나 캐스트될 수 있는 값의 범위를 제한해요. 예를 들어 999는 NUMBER(38,0)에는 들어가지만 NUMBER(2,0)에는 들어가지 않아요.

정밀도는 허용되는 총 자릿수이므로, 소수점 왼쪽의 자릿수가 컬럼 정밀도에서 스케일을 뺀 값을 초과하면 NUMBER 컬럼에 값을 로드할 수 없어요. 예를 들어 NUMBER(20, 2)는 소수점 왼쪽에 18자리, 오른쪽에 2자리를 허용해 총 20자리가 돼요.

최대 스케일, 즉 소수점 오른쪽의 자릿수는 37이에요. 유효 숫자가 38개 미만이지만 최하위 유효 숫자가 37번째 소수 자리 너머에 있는 숫자 — 예를 들어 0.0000000000000000000000000000000000000012 (1.2e-39) — 는 일부 자릿수의 정밀도를 잃지 않고는 표현할 수 없어요.

Note

데이터를 더 낮은 정밀도의 다른 데이터 타입으로 변환했다가 다시 높은 정밀도의 데이터 타입으로 변환하면 정밀도를 잃을 수 있어요. 예를 들어 NUMBER(38,37) 값을 DOUBLE 값(약 15자리 십진 정밀도)으로 변환했다가 다시 NUMBER로 변환하면 정밀도가 손실돼요.

Snowflake는 또한 더 넓은 범위의 값을 허용하는 FLOAT 데이터 타입을 지원하지만, 정밀도는 낮아요.

DECIMAL , DEC , NUMERIC

NUMBER와 동의어예요.

INT , INTEGER , BIGINT , SMALLINT , TINYINT , BYTEINT

NUMBER와 동의어지만, 정밀도와 스케일을 지정할 수 없다는 점이 달라요(즉, 항상 기본값인 NUMBER(38, 0)이 돼요). 따라서 모든 INTEGER 데이터 타입의 값 범위는 -99999999999999999999999999999999999999부터 +99999999999999999999999999999999999999(포함)까지의 모든 정숫값이에요.

TINYINT, BYTEINT 같은 다양한 이름들은 다른 시스템에서의 이식(porting)을 단순화하고, 지정된 타입의 컬럼에 대해 기대되는 값 범위를 시사하기 위한 거예요.

저장 크기에 대한 정밀도와 스케일의 영향

정밀도 — 총 자릿수 — 는 저장에 영향을 주지 않아요. NUMBER(2,0)과 NUMBER(38,0) 같은 서로 다른 정밀도의 컬럼에 저장되는 같은 숫자의 저장 요구량은 동일해요. 각 마이크로파티션(micro-partition)에 대해 Snowflake는 주어진 컬럼의 최솟값과 최댓값을 결정하고, 그 정보를 사용해 파티션에서 해당 컬럼의 모든 값에 대한 저장 크기를 결정해요. 예를 들어:

  • 컬럼이 -128+127 사이의 값만 포함하면 각 값은 1바이트(압축 전)를 소비해요.
  • 컬럼의 최댓값이 10000000이면 각 값은 4바이트(압축 전)를 소비해요.

그러나 스케일 — 소수점 뒤의 자릿수 — 는 저장에 영향을 줘요. 예를 들어 같은 값을 NUMBER(10,5) 타입 컬럼에 저장하면 NUMBER(5,0)보다 더 많은 공간을 소비해요. 또한 스케일이 큰 값을 처리하면 약간 더 느리고 더 많은 메모리를 소비할 수 있어요.

공간을 절약하기 위해 Snowflake는 저장에 쓰기 전에 값을 압축해요. 압축량은 데이터 값과 다른 요소에 따라 달라요.

테이블의 고정 소수점 데이터 타입 예제

다음 문은 다양한 고정 소수점 데이터 타입의 컬럼이 있는 테이블을 만들어요:

CREATE OR REPLACE TABLE test_fixed(
  num0 NUMBER,
  num10 NUMBER(10,1),
  dec20 DECIMAL(20,2),
  numeric30 NUMERIC(30,3),
  int1 INT,
  int2 INTEGER);

DESC TABLE test_fixed;

+-----------+--------------+--------+-------+---------+-------------+------------+-------+------------+---------+-------------+----------------+
| name      | type         | kind   | null? | default | primary key | unique key | check | expression | comment | policy name | privacy domain |
|-----------+--------------+--------+-------+---------+-------------+------------+-------+------------+---------+-------------+----------------|
| NUM0      | NUMBER(38,0) | COLUMN | Y     | NULL    | N           | N          | NULL  | NULL       | NULL    | NULL        | NULL           |
| NUM10     | NUMBER(10,1) | COLUMN | Y     | NULL    | N           | N          | NULL  | NULL       | NULL    | NULL        | NULL           |
| DEC20     | NUMBER(20,2) | COLUMN | Y     | NULL    | N           | N          | NULL  | NULL       | NULL    | NULL        | NULL           |
| NUMERIC30 | NUMBER(30,3) | COLUMN | Y     | NULL    | N           | N          | NULL  | NULL       | NULL    | NULL        | NULL           |
| INT1      | NUMBER(38,0) | COLUMN | Y     | NULL    | N           | N          | NULL  | NULL       | NULL    | NULL        | NULL           |
| INT2      | NUMBER(38,0) | COLUMN | Y     | NULL    | N           | N          | NULL  | NULL       | NULL    | NULL        | NULL           |
+-----------+--------------+--------+-------+---------+-------------+------------+-------+------------+---------+-------------+----------------+

부동 소수점(floating-point) 숫자 데이터 타입

Snowflake는 부동 소수점 숫자에 다음 데이터 타입을 지원해요.

FLOAT , FLOAT4 , FLOAT8

FLOAT, FLOAT4, FLOAT8 이름은 다른 시스템과의 호환성을 위한 거예요. Snowflake는 세 가지 모두를 64비트 부동 소수점 숫자로 취급해요.

정밀도

Snowflake는 배정밀도(64비트) IEEE 754 부동 소수점 숫자를 사용해요.

정밀도는 약 15자리예요. 예를 들어 정수의 범위는 -9007199254740991부터 +9007199254740991(-2^53 + 1부터 +2^53 - 1)까지예요. 부동 소수점 값은 약 10^-308부터 10^+308까지의 범위를 가질 수 있어요. Snowflake는 약 10^-324와 10^-308 사이의 더 극단적인 값도 낮은 정밀도로 표현할 수 있어요. 자세한 내용은 배정밀도 숫자에 대한 Wikipedia 문서를 참고해요.

Snowflake는 더 큰 정밀도를 허용하는 고정 소수점 데이터 타입 NUMBER를 지원하지만, 지수 범위는 더 작아요.

특수 값

Snowflake는 FLOAT에 대해 다음 특수 값을 지원해요.

  • 'NaN' (숫자가 아님, not a number)
  • 'inf' (무한대)
  • '-inf' (음의 무한대)

'NaN', 'inf', '-inf' 기호는 작은따옴표 안에 있어야 하며 대소문자를 구분하지 않아요.

'NaN'의 비교 의미는 다음 방식으로 IEEE 754 표준과 달라요.

조건 Snowflake IEEE 754 비고
'NaN' = 'NaN' TRUE FALSE Snowflake에서는 'NaN' 값이 모두 같아요.
'NaN' > X (X가 무한대를 포함한 NaN 자신이 아닌 어떤 FLOAT 값) TRUE FALSE Snowflake에서는 'NaN'이 무한대를 포함한 다른 모든 FLOAT 값보다 커요.
반올림 오류

부동 소수점 연산은 최하위 자릿수에 작은 반올림 오류가 있을 수 있어요. 반올림 오류는 삼각, 통계, 지리 공간 함수를 포함한 모든 유형의 부동 소수점 처리에서 발생할 수 있어요.

다음 목록은 반올림 오류에 대한 고려 사항을 보여 줘요.

  • 오류는 쿼리를 실행할 때마다 달라질 수 있어요.
  • 피연산자가 서로 다른 정밀도나 스케일을 가질 때 오류가 더 커질 수 있어요.
  • 특히 SUM이나 AVG 같은 집계 함수가 많은 수의 행을 처리할 때 오류가 누적될 수 있어요. 집계 전에 고정 소수점 데이터 타입으로 캐스팅하면 이런 오류를 줄이거나 제거할 수 있어요.
  • 반올림 오류는 SQL에서 작업할 때뿐만 아니라 Snowflake 내부에서 실행되는 다른 코드에서도 발생할 수 있어요 — 예를 들어 UDF저장 프로시저에서 실행되는 Java, JavaScript, Python 코드에서요.
  • 두 부동 소수점 숫자를 비교할 때 Snowflake는 정확한 동등성(equality)이 아니라 대략적인 동등성을 비교하길 권장해요.

이런 유형의 근사 오류는 정확한 DECFLOAT 데이터 타입을 사용해 피할 수 있을 수도 있어요.

DOUBLE , DOUBLE PRECISION , REAL

FLOAT와 동의어예요.

테이블의 부동 소수점 데이터 타입 예제

다음 문은 다양한 부동 소수점 데이터 타입의 컬럼이 있는 테이블을 만들어요:

CREATE OR REPLACE TABLE test_float(
  double1 DOUBLE,
  float1 FLOAT,
  dp1 DOUBLE PRECISION,
  real1 REAL);

DESC TABLE test_float;

+---------+-------+--------+-------+---------+-------------+------------+-------+------------+---------+-------------+----------------+
| name    | type  | kind   | null? | default | primary key | unique key | check | expression | comment | policy name | privacy domain |
|---------+-------+--------+-------+---------+-------------+------------+-------+------------+---------+-------------+----------------|
| DOUBLE1 | FLOAT | COLUMN | Y     | NULL    | N           | N          | NULL  | NULL       | NULL    | NULL        | NULL           |
| FLOAT1  | FLOAT | COLUMN | Y     | NULL    | N           | N          | NULL  | NULL       | NULL    | NULL        | NULL           |
| DP1     | FLOAT | COLUMN | Y     | NULL    | N           | N          | NULL  | NULL       | NULL    | NULL        | NULL           |
| REAL1   | FLOAT | COLUMN | Y     | NULL    | N           | N          | NULL  | NULL       | NULL    | NULL        | NULL           |
+---------+-------+--------+-------+---------+-------------+------------+-------+------------+---------+-------------+----------------+

Note

DESC TABLE 명령의 type 컬럼은 FLOAT뿐 아니라 FLOAT의 동의어(예: DOUBLE, DOUBLE PRECISION, REAL)에 대해서도 데이터 타입 FLOAT를 표시해요.

DECFLOAT

십진 부동 소수점(decimal float, DECFLOAT) 데이터 타입은 숫자를 최대 38개의 유효 자릿수까지 정확하게 저장하고, 동적 base-10 지수를 사용해 매우 크거나 작은 값을 표현해요. 지수 범위는 -16383부터 16384까지로, 약 -10^(16384)와 10^(16384) 사이의 값을 허용해요. DECFLOAT 데이터 타입은 가변 스케일을 지원해서, 저장되는 특정 값에 따라 스케일이 달라져요. 값을 근사치로 표현하는 FLOAT 데이터 타입과 달리, DECFLOAT 데이터 타입은 지정된 정밀도에서 정확한 값을 표현해요.

DECFLOAT 데이터 타입은 FLOAT 데이터 타입이 지원하는 다음 특수 값을 지원하지 않아요: 'NaN'(숫자가 아님), 'inf'(무한대), '-inf'(음의 무한대).

DECFLOAT 데이터 타입의 사용 사례

같은 컬럼에서 정확한 십진 결과와 넓고 가변적인 스케일이 모두 필요할 때 DECFLOAT 데이터 타입을 사용해요.

DECFLOAT 데이터 타입은 다음 일반적인 사용 사례에 적합해요.

  • 데이터를 수집(ingest)하고 있고, 들어오는 숫자 값의 스케일이 알려지지 않았거나 매우 가변적인 경우
  • 정확한 숫자 값이 필요한 경우; 예를 들어 원장(ledgers), 세금, 컴플라이언스
  • IEEE 754-십진 표현이나 128비트 십진수에 의존하는 시스템에서 마이그레이션하는 경우. 이러한 마이그레이션은 다른 Snowflake 데이터 타입의 정밀도나 범위 제한으로 막힐 수 있어요.
  • 고정밀 숫자 값을 합하거나, 곱하거나, 나눌 때 Number out of representable range 오류를 피하고 싶은 경우

예를 들어 DECFLOAT 데이터 타입은 다음 특정 사용 사례에 사용할 수 있어요.

  • Oracle DECIMAL 또는 DB2 DECFLOAT 컬럼에서 이질적으로 스케일이 다른 데이터를 수집하는 경우
  • 예측하기 어려운 결과 스케일의 계산이 포함된 금융 모델링을 수행하는 경우
  • 나노 단위에서 천문학적 단위까지 흔들리는 과학적 측정을 실행하는 경우

고정 스케일의 숫자 컬럼에는 NUMBER 데이터 타입을, 부정확한 결과가 허용되는 고처리량 분석에는 FLOAT 데이터 타입을 계속 사용할 수 있어요.

DECFLOAT 데이터 타입에 대한 사용 메모
  • 연산이 38자리보다 많은 결과를 생성하면 DECFLOAT 값은 현재 반올림 모드에 따라 최하위 자릿수가 반올림되어 38자리 정밀도로 반올림돼요. Snowflake는 DECFLOAT 값에 half up 반올림 모드를 사용해요.
  • DECFLOAT 값을 지정하거나 DECFLOAT 값으로 캐스트할 때, SQL에서 숫자 리터럴을 사용하지 마세요. SQL에서 숫자 리터럴을 사용하면 값이 DECFLOAT 값으로 캐스트되기 전에 NUMBER나 FLOAT 값으로 해석되어 범위 오류나 정확성 손실이 발생할 수 있어요. 대신 문자열 리터럴 — 예: SELECT ‘<value>’::DECFLOAT — 또는 DECFLOAT 리터럴 — 예: SELECT DECFLOAT ‘<value>’ — 을 사용해요.
  • 연산이 DECFLOAT 값과 다른 숫자 타입의 값을 섞을 때, 강제(coercion)는 DECFLOAT 값을 선호해요. 예를 들어 NUMBER 타입과 DECFLOAT 타입의 값을 더하면 결과는 DECFLOAT 값이에요.
  • DECFLOAT 값을 반구조적 데이터 타입(예: VARIANT)과 구조적 데이터 타입(예: ARRAY, OBJECT, MAP)에 저장할 수 있어요.
  • DECFLOAT 타입을 사용하면 저장 공간 소비가 증가할 수 있어요.
DECFLOAT 데이터 타입을 지원하는 드라이버와 드라이버 버전

다음 Snowflake 드라이버와 드라이버 버전이 DECFLOAT 데이터 타입을 지원해요. DECFLOAT를 지원하는 버전으로 드라이버를 업데이트해야 할 수 있어요.

드라이버 최소 지원 버전 비고
Snowflake Connector for Python 3.14.1 pandas DataFrame은 DECFLOAT 타입을 지원하지 않아요.
ODBC 3.12.0 없음.
JDBC 3.27.0 없음.
Go Snowflake Driver 1.17.0 없음.
SQL API 2.0.0 없음.

지원하지 않는 드라이버는 DECFLOAT 값을 TEXT 값으로 취급해요. 일부 드라이버의 경우 DECFLOAT 타입을 언어 고유 타입에 매핑하려면 드라이버 파라미터를 설정해야 해요. 자세한 내용은 드라이버를 참고해요.

DECFLOAT 데이터 타입의 제한 사항

DECFLOAT 타입에는 다음 제한 사항이 적용돼요.

DECFLOAT 데이터 타입의 예제

다음 예제들은 DECFLOAT 데이터 타입을 사용해요.

  • DECFLOAT와 FLOAT의 차이 보여주기
  • 집계 함수와 함께 DECFLOAT 값 사용하기
DECFLOAT와 FLOAT의 차이 보여주기

다음 예제는 DECFLOAT와 FLOAT 데이터 타입의 차이를 보여 줘요.

  1. DECFLOAT 컬럼과 FLOAT 컬럼이 있는 테이블을 만들고, 두 타입 모두에 같은 값을 테이블에 삽입해요.
CREATE OR REPLACE TABLE decfloat_sample (
  id INT,
  decfloat_val DECFLOAT,
  float_val FLOAT);

INSERT INTO decfloat_sample VALUES
  (
 1,
 DECFLOAT '123e7000',
 FLOAT '123e7000'
  ),
  (
 2,
 12345678901234567890123456789::DECFLOAT,
 12345678901234567890123456789::FLOAT
  ),
  (
 3,
 '-4.2e-5432'::DECFLOAT,
 '-4.2e-5432'::FLOAT
  ),
  (
 4,
 '1.00000000000000000000000000000000000014'::DECFLOAT,
 '1.00000000000000000000000000000000000014'::FLOAT
  ),
  (
 5,
 '1.00000000000000000000000000000000000015'::DECFLOAT,
 '1.00000000000000000000000000000000000015'::FLOAT
  );

이 문은 다음 방식으로 DECFLOAT 값을 삽입해요.

  • 첫 번째 값은 DECFLOAT 리터럴을 사용해 삽입돼요.
  • 두 번째 값은 INTEGER 값을 DECFLOAT 값으로 캐스트해 삽입돼요.
  • 세 번째, 네 번째, 다섯 번째 값은 VARCHAR 값을 DECFLOAT 값으로 캐스트해 삽입돼요.
  1. 타입을 보여주려면 DESC TABLE 명령으로 테이블을 설명해요.

테이블 정의에서 두 컬럼 모두 정밀도를 지정하지 않았지만, 출력은 DECFLOAT 데이터 타입이 최대 38개의 유효 자릿수 정밀도를 지원함을 보여 줘요.

DESC TABLE decfloat_sample;

+--------------+--------------+--------+-------+---------+-------------+------------+-------+------------+---------+-------------+----------------+
| name         | type         | kind   | null? | default | primary key | unique key | check | expression | comment | policy name | privacy domain |
|--------------+--------------+--------+-------+---------+-------------+------------+-------+------------+---------+-------------+----------------|
| ID           | NUMBER(38,0) | COLUMN | Y     | NULL    | N           | N          | NULL  | NULL       | NULL    | NULL        | NULL           |
| DECFLOAT_VAL | DECFLOAT(38) | COLUMN | Y     | NULL    | N           | N          | NULL  | NULL       | NULL    | NULL        | NULL           |
| FLOAT_VAL    | FLOAT        | COLUMN | Y     | NULL    | N           | N          | NULL  | NULL       | NULL    | NULL        | NULL           |
+--------------+--------------+--------+-------+---------+-------------+------------+-------+------------+---------+-------------+----------------+
  1. 값의 차이를 보여주려면 SELECT 문으로 테이블을 쿼리해요.
SELECT * FROM decfloat_sample;

+----+-----------------------------------------+------------------------+
| ID | DECFLOAT_VAL                            |              FLOAT_VAL |
|----+-----------------------------------------+------------------------|
|  1 | 1.23e7002                               | inf                    |
|  2 | 12345678901234567890123456789           |   1.23456789012346e+28 |
|  3 | -4.2e-5432                              |  -0                    |
|  4 | 1.0000000000000000000000000000000000001 |   1                    |
|  5 | 1.0000000000000000000000000000000000002 |   1                    |
+----+-----------------------------------------+------------------------+

출력은 다음 차이를 보여 줘요.

  • 첫 번째 행은 DECFLOAT 타입이 FLOAT 타입보다 더 넓은 값 범위를 지원함을 보여 줘요. DECFLOAT 값은 매우 커요(1.23e7002). FLOAT 값은 inf인데, 이는 값이 FLOAT 타입이 표현할 수 있는 어떤 값보다 크다는 뜻이에요.
  • 두 번째 행은 DECFLOAT 타입이 지정된 값을 정확히 유지함을 보여 줘요. FLOAT 값은 과학적 표기법으로 저장된 근사치예요.
  • 세 번째 행은 DECFLOAT 타입이 매우 작은 값(-4.2e-5432)을 지원함을 보여 줘요. FLOAT 값은 -0으로 근사돼요.
  • 네 번째와 다섯 번째 행은 DECFLOAT 타입이 최대 38자리 정밀도를 지원하고 그 한도를 넘는 값에는 반올림 규칙을 사용함을 보여 줘요. 두 행 모두에서 FLOAT 값은 1로 근사돼요.
집계 함수와 함께 DECFLOAT 값 사용하기

다음 예제는 집계 함수와 함께 DECFLOAT 값을 사용해요.

  1. 테이블을 만들고 DECFLOAT 값을 테이블에 삽입해요.
CREATE OR REPLACE TABLE decfloat_agg_sample (decfloat_val DECFLOAT);

INSERT INTO decfloat_agg_sample VALUES
  (DECFLOAT '1e1000'),
  (DECFLOAT '-2.47e999'),
  (DECFLOAT '22e-75');
  1. 몇 가지 집계 함수로 테이블을 쿼리해요.
SELECT SUM(decfloat_val),
    AVG(decfloat_val),
    MAX(decfloat_val),
    MIN(decfloat_val)
  FROM decfloat_agg_sample;

+-------------------+-------------------+-------------------+-------------------+
| SUM(DECFLOAT_VAL) | AVG(DECFLOAT_VAL) | MAX(DECFLOAT_VAL) | MIN(DECFLOAT_VAL) |
|-------------------+-------------------+-------------------+-------------------|
| 7.53e999          | 2.51e999          | 1e1000            | -2.47e999         |
+-------------------+-------------------+-------------------+-------------------+

숫자 상수(Numeric constants)

상수(constants)리터럴(literals) 이라고도 함 — 는 고정 데이터 값을 말해요. 숫자 상수에는 다음 포맷이 지원돼요.

[+-][digits][.digits][e[+-]digits]

여기서:

  • + 또는 -는 양수 또는 음수 값을 나타내요. 기본값은 양수예요.
  • digits는 0부터 9까지의 하나 이상의 숫자예요.
  • e(또는 E)는 과학적 표기법의 지수를 나타내요. 지수 표시가 있으면 그 뒤에 최소한 하나의 숫자가 와야 해요.

다음 숫자들은 모두 지원되는 숫자 상수의 예시예요.

15
+1.34
0.2
15e-03
1.234E2
1.234E+2
-1

더 알아보기 (Learn more)