[ETL] 이기종 DBMS 데이터 타입 매핑 표준 정리: PostgreSQL, Iceberg, Spark
1. 개요
여러 업무 시스템의 데이터를 하나의 데이터 플랫폼으로 모으는 파이프라인에서는 데이터 타입 변환이 항상 따라온다. 소스는 PostgreSQL, MySQL, Oracle, SQL Server처럼 제각각이고, 적재 대상은 데이터 마트(PostgreSQL), 데이터 레이크(Iceberg), 처리 엔진(Spark)으로 나뉜다.
같은 정수라도 DBMS마다 이름이 다르다. INT4, MEDIUMINT, NUMBER(9,0), INT가 모두 32비트 정수 계열이다. 이 대응 관계를 파이프라인 코드 곳곳에 흩어 두면 소스가 하나 늘 때마다 변환 로직을 다시 짜게 된다.
이 글에서는 이 문제를 매핑 표 두 장으로 정리한다. 본문의 타입 표는 실제 운영 중인 수집 파이프라인에서 쓰는 기준을 일반화한 예시다.
2. 매핑 체계: 2단계 변환
매핑은 두 단계로 나눈다.
소스 DBMS 타입 → (1단계: DBMS별 정규화) → 표준 타입 → (2단계: 매핑 표) → PostgreSQL / Iceberg / Spark
- 1단계, DBMS별 정규화: 각 DBMS에서 조회한 타입명을 표준 타입으로 통일한다. 예를 들어 PostgreSQL 카탈로그의
int4는INTEGER로, MySQL의TINYINT(1)은BOOLEAN으로 정규화한다. - 2단계, 표준 매핑: 표준 타입을 기준으로 PostgreSQL, Iceberg, Spark 타입을 한 번에 결정한다.
이렇게 나누는 이유는 조합 폭발을 막기 위해서다. 소스 DBMS가 N개, 적재 대상이 M개면 직접 매핑은 N×M 조합이 필요하다. 중간에 표준 타입을 두면 소스가 늘 때 정규화 표 한 장만 추가하면 되고, 2단계 매핑 표는 그대로 재사용한다.
3. 표준 데이터 타입 매핑 표
PostgreSQL 타입을 기준 축으로 두고, Iceberg와 Spark의 대응 타입, 그리고 이 행으로 정규화되는 소스 타입(매핑 전 데이터 타입)을 정리한 표다.
정밀도 표기(n, p, s)가 붙는 타입은 기본형과 동일한 타입으로 매핑한다.
| No. | PostgreSQL | Iceberg | Spark | 설명 | 매핑 전 데이터 타입 |
|---|---|---|---|---|---|
| 1 | BIGINT | long | LongType() | 64비트 정수 | BIGINT, INT64, LONG |
| 2 | BIGINT[] | list<long> | ArrayType(LongType()) | 64비트 정수 배열 | BIGINT[], LIST(INT64) |
| 3 | BIGSERIAL | long | LongType() | 자동 증가 64비트 정수 (BIGINT 기반) | BIGSERIAL |
| 4 | BIT | binary | BinaryType() | 비트 데이터 타입 | BIT |
| 5 | BIT(n) | binary | BinaryType() | 비트 데이터 타입 (길이 지정) | BIT(n) |
| 6 | BOOLEAN | boolean | BooleanType() | TRUE 또는 FALSE 저장 (1비트) | BOOLEAN |
| 7 | BOOLEAN[] | list<boolean> | ArrayType(BooleanType()) | BOOLEAN 값 배열 | BOOLEAN[], LIST(BOOLEAN) |
| 8 | BPCHAR | string | StringType() | 고정 길이 문자형 (CHAR과 동일, 내부 표현) | BPCHAR |
| 9 | BPCHAR(n) | string | StringType() | 고정 길이 문자형 (CHAR과 동일, 내부 표현) | BPCHAR(n) |
| 10 | BPCHAR[] | list<string> | ArrayType(StringType()) | 고정 길이 문자형 배열 | BPCHAR[] |
| 11 | BPCHAR(n)[] | list<string> | ArrayType(StringType()) | 고정 길이 문자형 배열 | BPCHAR(n)[] |
| 12 | BYTEA | binary | BinaryType() | 바이너리 데이터 저장 (이미지, 파일, 암호화된 데이터) | BYTEA, BINARY, BLOB, BFILE, FIXED_LEN_BYTE_ARRAY, IMAGE, LONGBLOB, MEDIUMBLOB, RAW(n), TINYBLOB, VARBINARY, LONG RAW |
| 13 | BYTEA[] | list<binary> | ArrayType(BinaryType()) | 바이너리 데이터 배열 | BYTEA[] |
| 14 | CHAR | string | StringType() | 고정 길이 문자 | CHAR, CHARACTER, NCHAR |
| 15 | CHAR(n) | string | StringType() | 고정 길이 문자 | CHAR(n), CHARACTER(n), NCHAR(n) |
| 16 | CHAR[] | list<string> | ArrayType(StringType()) | 고정 길이 문자 배열 | CHAR[], CHARACTER[] |
| 17 | CHAR(n)[] | list<string> | ArrayType(StringType()) | 고정 길이 문자 배열 | CHAR(n)[], CHARACTER(n)[] |
| 18 | DATE | date | DateType() | 연-월-일 날짜 데이터 | DATE, INT32 (DATE) |
| 19 | DECIMAL | decimal | DecimalType() | 고정 소수점 숫자 (정확한 소수 연산 가능) | DECIMAL |
| 20 | DECIMAL(p,0) | decimal(p,0) | DecimalType(p,0) | p자리 정수 (소수점 없음) | DECIMAL(p) |
| 21 | DECIMAL(p,s) | decimal(p,s) | DecimalType(p,s) | p자리 중 소수 s자리 포함하는 고정 소수점 숫자 | DECIMAL(p,s) |
| 22 | DOUBLE PRECISION | double | DoubleType() | 64비트 부동소수점 (IEEE 754 표준) | DOUBLE PRECISION, BINARY_DOUBLE, DOUBLE, DOUBLE UNSIGNED, FLOAT, FLOAT(63) |
| 23 | DOUBLE PRECISION[] | list<double> | ArrayType(DoubleType()) | 64비트 부동소수점 배열 | DOUBLE PRECISION[], LIST(DOUBLE) |
| 24 | GEOGRAPHY | string | StringType() | 지리 공간 데이터 (PostGIS 확장 필요) | GEOGRAPHY |
| 25 | GEOMETRY | string | StringType() | 기하학적 공간 데이터 (PostGIS 확장 필요) | GEOMETRY |
| 26 | INTEGER | int | IntegerType() | 32비트 정수 | INTEGER, INT, INT4, INT32, MEDIUMINT |
| 27 | INTEGER[] | list<int> | ArrayType(IntegerType()) | 32비트 정수 배열 | INTEGER[], LIST(INT32) |
| 28 | JSON | string | StringType() | JSON 데이터 (텍스트 기반) | JSON |
| 29 | JSONB | string | StringType() | JSON 데이터 (이진 저장, 더 빠른 검색) | JSONB, MAP, STRUCT |
| 30 | NUMERIC | decimal | DecimalType() | 정확한 숫자 저장 (고정 소수점) | NUMERIC, FLOAT UNSIGNED |
| 31 | NUMERIC(10,0) | decimal(10,0) | DecimalType(10,0) | 10자리 정수 (소수점 없음) | INT UNSIGNED, INTEGER UNSIGNED, MEDIUMINT UNSIGNED |
| 32 | NUMERIC(10,4) | decimal(10,4) | DecimalType(10,4) | 10자리 중 소수점 4자리 포함 | SMALLMONEY |
| 33 | NUMERIC(19,4) | decimal(19,4) | DecimalType(19,4) | 화폐 데이터 (19자리, 소수 4자리 포함) | MONEY |
| 34 | NUMERIC(20,0) | decimal(20,0) | DecimalType(20,0) | 정확한 정수 저장 (최대 20자리) | BIGINT UNSIGNED |
| 35 | NUMERIC(3,0) | decimal(3,0) | DecimalType(3,0) | 3자리 정수 (소수점 없음) | TINYINT UNSIGNED |
| 36 | NUMERIC(5,0) | decimal(5,0) | DecimalType(5,0) | 5자리 정수 (소수점 없음) | SMALLINT UNSIGNED |
| 37 | NUMERIC(p,0) | decimal(p,0) | DecimalType(p,0) | p자리 정수 (소수점 없음) | NUMERIC(p) |
| 38 | NUMERIC(p,s) | decimal(p,s) | DecimalType(p,s) | p자리 중 소수 s자리 포함하는 고정 소수점 숫자 | NUMBER(p,s), NUMERIC(p,s), DECIMAL(p,s) UNSIGNED |
| 39 | REAL | float | FloatType() | 32비트 부동소수점 (IEEE 754 표준) | REAL, FLOAT(24), BINARY_FLOAT |
| 40 | REAL[] | list<float> | ArrayType(FloatType()) | 32비트 부동소수점 배열 | REAL[], LIST(FLOAT) |
| 41 | SERIAL | int | IntegerType() | 자동 증가 32비트 정수 (INTEGER 기반) | SERIAL |
| 42 | SMALLINT | int | ShortType() | 16비트 정수 | SMALLINT, TINYINT, YEAR |
| 43 | SMALLINT[] | list<int> | ArrayType(ShortType()) | 16비트 정수 배열 | SMALLINT[] |
| 44 | SMALLSERIAL | int | ShortType() | 자동 증가 16비트 정수 (SMALLINT 기반) | SMALLSERIAL |
| 45 | TEXT | string | StringType() | 무제한 길이 문자열 | TEXT, CLOB, DEPRECATED, ENUM, LONGTEXT, MEDIUMTEXT, NCLOB, NTEXT, ROWID, TINYTEXT |
| 46 | TEXT[] | list<string> | ArrayType(StringType()) | 문자열 배열 | TEXT[], LIST(STRING) |
| 47 | TIME | time | StringType() | 시간 데이터 (시간, 분, 초) | TIME |
| 48 | TIME(s) | time | StringType() | 시간 데이터 (정밀도 포함) | TIME(s) |
| 49 | TIMESTAMP | timestamp | TimestampType() | 날짜 및 시간 (타임존 없음) | TIMESTAMP, DATETIME, DATETIME2, INT64 (TIMESTAMP_MILLIS), INT96, SMALLDATETIME |
| 50 | TIMESTAMP(s) | timestamp | TimestampType() | 날짜 및 시간 (타임존 없음, 정밀도 포함) | TIMESTAMP(s) |
| 51 | TIMESTAMPTZ | timestamp | TimestampType() | 날짜 및 시간 (타임존 포함) | TIMESTAMPTZ, TIMESTAMP WITH TIME ZONE, TIMESTAMP WITH LOCAL TIME ZONE, DATETIMEOFFSET |
| 52 | TIMESTAMPTZ(s) | timestamp | TimestampType() | 날짜 및 시간 (타임존 포함, 정밀도 포함) | TIMESTAMPTZ(s) |
| 53 | TIMETZ | time | StringType() | 시간 데이터 (타임존 포함) | TIMETZ, TIME WITH TIME ZONE |
| 54 | TIMETZ(s) | time | StringType() | 시간 데이터 (타임존 포함, 정밀도 포함) | TIMETZ(s) |
| 55 | UUID | string | StringType() | 고유 식별자 (Universally Unique Identifier) | UUID |
| 56 | VARCHAR | string | StringType() | 가변 길이 문자열 | VARCHAR, VARCHAR2, NVARCHAR, NVARCHAR2, CHARACTER VARYING |
| 57 | VARCHAR(n) | string | StringType() | 가변 길이 문자열 | VARCHAR(n), VARCHAR2(n), NVARCHAR(n), NVARCHAR2(n), CHARACTER VARYING(n) |
| 58 | VARCHAR[] | list<string> | ArrayType(StringType()) | 가변 길이 문자열 배열 | VARCHAR[], CHARACTER VARYING[] |
| 59 | VARCHAR(n)[] | list<string> | ArrayType(StringType()) | 가변 길이 문자열 배열 | VARCHAR(n)[], CHARACTER VARYING[] |
| 60 | XML | string | StringType() | XML 데이터 (구조화된 문서 저장) | XML, XMLTYPE |
4. 타입 계열별 설계 포인트
표의 행 수는 많지만 설계 결정은 몇 가지 계열로 압축된다.
4.1 정수: UNSIGNED는 한 단계 큰 DECIMAL로 승격
PostgreSQL, Iceberg, Spark 모두 부호 없는 정수 타입이 없다. MySQL의 UNSIGNED 계열을 같은 크기의 부호 있는 정수에 담으면 상위 절반 범위가 오버플로된다.
그래서 UNSIGNED는 해당 범위를 통째로 담을 수 있는 고정 소수점 타입으로 승격한다.
| 소스 (MySQL) | 표준 매핑 |
|---|---|
| TINYINT UNSIGNED | NUMERIC(3,0) |
| SMALLINT UNSIGNED | NUMERIC(5,0) |
| INT UNSIGNED, MEDIUMINT UNSIGNED | NUMERIC(10,0) |
| BIGINT UNSIGNED | NUMERIC(20,0) |
MySQL의 TINYINT(1)은 관례적으로 불리언으로 쓰이므로 정수가 아니라 BOOLEAN으로 정규화한다.
4.2 실수: 정밀도에 따라 REAL과 DOUBLE PRECISION으로 분기
FLOAT라는 이름은 DBMS마다 가리키는 정밀도가 다르다. 정밀도 기준으로 32비트 계열과 64비트 계열을 나눈다.
- REAL (32비트):
FLOAT(24),BINARY_FLOAT(Oracle), SQL Server의FLOAT(1~24) - DOUBLE PRECISION (64비트):
FLOAT(63),BINARY_DOUBLE(Oracle), MySQL의DOUBLE, SQL Server의FLOAT(>24)
화폐 타입은 부동소수점 오차를 피해야 하므로 고정 소수점으로 보낸다. SQL Server의 MONEY는 NUMERIC(19,4), SMALLMONEY는 NUMERIC(10,4)다.
4.3 문자열: 결국 전부 string으로 수렴
고정 길이(CHAR), 가변 길이(VARCHAR), 무제한(TEXT, CLOB) 모두 Iceberg에서는 string, Spark에서는 StringType() 하나로 수렴한다. 길이 제약은 소스 시스템의 스키마 관심사이고, 분석 플랫폼 쪽에서는 유지할 실익이 없다.
Oracle의 LONG 타입은 Oracle 스스로 사용 중단(deprecated)을 권고하는 타입이라 TEXT 계열로 흡수한다. MySQL의 ENUM도 코드 값 문자열로 취급해 TEXT로 보낸다.
4.4 시간: Spark에 time 타입이 없다
이 매핑 표에서 가장 주의할 지점이다. Iceberg는 time 타입을 지원하지만 Spark에는 시각(time-of-day)만 담는 타입이 없다. 그래서 TIME, TIMETZ 계열은 Iceberg에는 time으로 적재하더라도 Spark 스키마에서는 StringType()으로 다룬다.
타임존 포함 여부와 무관하게 TIMESTAMP, TIMESTAMPTZ는 모두 Spark TimestampType() 하나로 매핑한다. MySQL DATETIME, SQL Server DATETIME2, SMALLDATETIME, Parquet의 INT96도 같은 행으로 정규화된다.
4.5 반정형과 특수 타입: string으로 보존
JSON, JSONB, XML, UUID, 공간 타입(GEOMETRY, GEOGRAPHY)은 모두 문자열로 저장한다. 원본 표현을 그대로 보존하고, 해석은 조회 시점에 맡기는 방식이다.
Parquet의 중첩 타입 MAP, STRUCT도 JSON 문자열로 직렬화해 JSONB 행으로 정규화한다. 바이너리 계열(BLOB, IMAGE, RAW 등)은 전부 BYTEA/binary로 모은다.
5. DBMS별 정규화 표
1단계 정규화에서 쓰는 표다. 분류 열은 각 DBMS에서 식별되는 타입(카탈로그 내부명 또는 판별 조건)이고, 데이터 타입 열이 정규화 결과다. 이 결과 값이 3장 매핑 표의 매핑 전 데이터 타입 열에 대응한다.
5.1 PostgreSQL
PostgreSQL은 카탈로그에서 내부 타입명으로 조회되는 경우가 많다. 배열 타입은 언더스코어 접두사(_int4)로 나타난다.
| No. | 분류 | 데이터 타입 |
|---|---|---|
| 1 | BOOL | BOOLEAN |
| 2 | _BOOL | BOOLEAN[] |
| 3 | BYTEA | BYTEA |
| 4 | _BYTEA | BYTEA[] |
| 5 | INT2 | SMALLINT |
| 6 | SMALLSERIAL | SMALLSERIAL |
| 7 | _INT2 | SMALLINT[] |
| 8 | INT4 | INTEGER |
| 9 | SERIAL | SERIAL |
| 10 | _INT4 | INTEGER[] |
| 11 | INT8 | BIGINT |
| 12 | BIGSERIAL | BIGSERIAL |
| 13 | _INT8 | BIGINT[] |
| 14 | FLOAT4 | REAL |
| 15 | _FLOAT4 | REAL[] |
| 16 | FLOAT8 | DOUBLE PRECISION |
| 17 | _FLOAT8 | DOUBLE PRECISION[] |
| 18 | NUMERIC | NUMERIC |
| 19 | BPCHAR | BPCHAR |
| 20 | CHARACTER | CHARACTER |
| 21 | VARCHAR | VARCHAR |
| 22 | TEXT | TEXT |
| 23 | GEOMETRY | GEOMETRY (PostGIS 필요) |
| 24 | GEOGRAPHY | GEOGRAPHY (PostGIS 필요) |
| 25 | JSON | JSON |
| 26 | JSONB | JSONB |
| 27 | UUID | UUID |
| 28 | _BPCHAR | BPCHAR[] |
| 29 | _CHARACTER | CHAR[] |
| 30 | _CHARACTER | CHARACTER[] |
| 31 | _VARCHAR | VARCHAR[] |
| 32 | _VARCHAR | CHARACTER VARYING[] |
| 33 | _TEXT | TEXT[] |
| 34 | TIMESTAMP(s) | TIMESTAMP |
| 35 | TIMESTAMP(s) | TIMESTAMP WITH TIME ZONE |
| 36 | TIMESTAMPTZ(s) | TIMESTAMPTZ |
| 37 | TIMESTAMPTZ(s) | TIME WITH TIME ZONE |
| 38 | TIME(s) | TIME |
| 39 | TIMETZ(s) | TIMETZ |
| 40 | DATE | DATE |
5.2 MySQL / MariaDB
| No. | 분류 | 데이터 타입 |
|---|---|---|
| 1 | BIT(1) | BIT(1) |
| 2 | TINYINT(1) | BOOLEAN |
| 3 | TINYINT | TINYINT |
| 4 | TINYINT UNSIGNED | TINYINT UNSIGNED |
| 5 | SMALLINT | SMALLINT |
| 6 | SMALLINT UNSIGNED | SMALLINT UNSIGNED |
| 7 | MEDIUMINT | MEDIUMINT |
| 8 | MEDIUMINT UNSIGNED | MEDIUMINT UNSIGNED |
| 9 | INT | INT |
| 10 | INTEGER | INTEGER |
| 11 | YEAR | YEAR |
| 12 | INT UNSIGNED | INT UNSIGNED |
| 13 | INTEGER UNSIGNED | INTEGER UNSIGNED |
| 14 | BIGINT | BIGINT |
| 15 | BIGINT UNSIGNED | BIGINT UNSIGNED |
| 16 | DECIMAL(x,y) | DECIMAL(x,y) |
| 17 | DECIMAL UNSIGNED | DECIMAL(x,y) UNSIGNED |
| 18 | FLOAT | FLOAT |
| 19 | FLOAT UNSIGNED | FLOAT UNSIGNED |
| 20 | DOUBLE | DOUBLE |
| 21 | DOUBLE UNSIGNED | DOUBLE UNSIGNED |
| 22 | CHAR | CHAR |
| 23 | VARCHAR | VARCHAR |
| 24 | TINYTEXT | TINYTEXT |
| 25 | MEDIUMTEXT | MEDIUMTEXT |
| 26 | TEXT | TEXT |
| 27 | LONGTEXT | LONGTEXT |
| 28 | JSON | JSON |
| 29 | ENUM | ENUM |
| 30 | DATE | DATE |
| 31 | TIME(s) | TIME |
| 32 | DATETIME | DATETIME |
| 33 | TIMESTAMP(s) | TIMESTAMP |
| 34 | TINYBLOB | TINYBLOB |
| 35 | MEDIUMBLOB | MEDIUMBLOB |
| 36 | BLOB | BLOB |
| 37 | LONGBLOB | LONGBLOB |
| 38 | BINARY | BINARY |
| 39 | VARBINARY | VARBINARY |
| 40 | BIT(n) | BIT(n) |
| 41 | GEOMETRY | GEOMETRY |
5.3 Oracle
Oracle의 NUMBER는 정밀도(precision)와 스케일(scale) 조합으로 실제 크기가 정해진다. 정규화 단계에서 조건 분기로 처리한다.
| No. | 분류 | 데이터 타입 |
|---|---|---|
| 1 | INTEGER | INT |
| 2 | INTEGER UNSIGNED | INT UNSIGNED |
| 3 | FLOAT | FLOAT |
| 4 | NUMBER(precision <= 9, scale == 0) | NUMBER(9,0) |
| 5 | NUMBER(9 < precision <= 18, scale == 0) | NUMBER(18,0) |
| 6 | NUMBER(18 < precision, scale == 0) | NUMBER(38,0) |
| 7 | NUMBER(scale != 0) | NUMBER(p,s) |
| 8 | BINARY_DOUBLE | BINARY_DOUBLE |
| 9 | BINARY_FLOAT | BINARY_FLOAT |
| 10 | REAL | FLOAT |
| 11 | CHAR | CHAR |
| 12 | NCHAR | NCHAR |
| 13 | VARCHAR | VARCHAR2 |
| 14 | NVARCHAR2 | NVARCHAR2 |
| 15 | VARCHAR2 | VARCHAR2 |
| 16 | LONG | DEPRECATED |
| 17 | ROWID | ROWID |
| 18 | NCLOB | NCLOB |
| 19 | CLOB | CLOB |
| 20 | XML | XMLTYPE |
| 21 | DATE | DATE |
| 22 | TIMESTAMP | TIMESTAMP |
| 23 | TIMESTAMP WITH LOCAL TIME ZONE | TIMESTAMP WITH LOCAL TIME ZONE |
| 24 | BLOB | BLOB |
| 25 | RAW | RAW(N) |
| 26 | LONG RAW | LONG RAW |
| 27 | BFILE | BFILE |
5.4 SQL Server
| No. | 분류 | 데이터 타입 |
|---|---|---|
| 1 | BIT | BIT |
| 2 | TINYINT | TINYINT |
| 3 | SMALLINT | SMALLINT |
| 4 | INTEGER | INT |
| 5 | INT | INT |
| 6 | BIGINT | BIGINT |
| 7 | NUMERIC(p,s) | NUMERIC(p,s) |
| 8 | DECIMAL(p,s) | DECIMAL(p,s) |
| 9 | MONEY | MONEY |
| 10 | SMALLMONEY | SMALLMONEY |
| 11 | FLOAT(1~24) | REAL |
| 12 | REAL | REAL |
| 13 | DOUBLE | FLOAT |
| 14 | FLOAT(>24) | FLOAT |
| 15 | CHAR | CHAR |
| 16 | NCHAR | NCHAR |
| 17 | VARCHAR | VARCHAR |
| 18 | NTEXT | NTEXT |
| 19 | NVARCHAR | NVARCHAR |
| 20 | TEXT | TEXT |
| 21 | XML | XML |
| 22 | DATE | DATE |
| 23 | TIME(s) | TIME |
| 24 | DATETIME(s) | DATETIME |
| 25 | DATETIME2(s) | DATETIME2 |
| 26 | DATETIMEOFFSET(s) | DATETIMEOFFSET |
| 27 | SMALLDATETIME | SMALLDATETIME |
| 28 | BINARY | BINARY |
| 29 | VARBINARY | VARBINARY |
| 30 | IMAGE | IMAGE |
5.5 Parquet
파일 기반 수집(Parquet)도 같은 체계로 정규화한다. Parquet은 논리 타입(logical type)이 물리 타입(physical type) 위에 얹히는 구조라, 분류 열이 논리 타입이고 데이터 타입 열이 물리 타입 기준 표기다.
| No. | 분류 | 데이터 타입 |
|---|---|---|
| 1 | INT_8 | INT32 |
| 2 | INT_16 | INT32 |
| 3 | DATE | INT32 (DATE) |
| 4 | TIMESTAMP_MILLIS | INT64 (TIMESTAMP_MILLIS) |
| 5 | INT64 | INT64 |
| 6 | INT96 | INT96 |
| 7 | BINARY | BINARY |
| 8 | FLOAT | FLOAT |
| 9 | DOUBLE | DOUBLE |
| 10 | BOOLEAN | BOOLEAN |
| 11 | FIXED_LEN_BYTE_ARRAY | FIXED_LEN_BYTE_ARRAY |
| 12 | DECIMAL | DECIMAL |
| 13 | LIST(STRING) | LIST(STRING) |
| 14 | LIST(BOOLEAN) | LIST(BOOLEAN) |
| 15 | LIST(TINYINT) | LIST(INT32) |
| 16 | LIST(SMALLINT) | LIST(INT32) |
| 17 | LIST(INT) | LIST(INT32) |
| 18 | LIST(BIGINT) | LIST(INT64) |
| 19 | LIST(FLOAT) | LIST(FLOAT) |
| 20 | LIST(DOUBLE) | LIST(DOUBLE) |
| 21 | Map<K,V> | MAP |
| 22 | STRUCT | STRUCT |
6. 정리
- 이기종 소스의 타입 변환은 DBMS별 정규화(1단계)와 표준 매핑(2단계) 으로 나누면 소스가 늘어도 매핑 표를 재사용할 수 있다.
- UNSIGNED 정수는 부호 있는 타입에 담기지 않으므로 범위를 커버하는 NUMERIC(p,0)으로 승격한다.
- FLOAT 계열은 이름이 아니라 정밀도 기준으로 REAL(32비트)과 DOUBLE PRECISION(64비트)을 나눈다.
- 문자열, 반정형(JSON, XML), UUID, 공간 타입은 string으로 수렴시키고 해석은 조회 시점에 맡긴다.
- Spark에는 time 타입이 없어 TIME 계열은 Spark에서 StringType() 으로 다룬다. Iceberg에는 time으로 적재할 수 있다.
- 화폐 타입(MONEY, SMALLMONEY)은 부동소수점이 아니라 고정 소수점(NUMERIC) 으로 보낸다.
Leave a comment