ANSI SQL
데이터 모델을 설계하는 과정에서 속성을 도출하고, 속성의 데이터 타입(Data Type)을 결정하는 과정은 꽤 복잡합니다. 그러나 지금까지 경험을 비추어보면, 다양한 상황을 고려하지 않고 데이터 타입을 선택하는 경우가 많았습니다. 이 결과로 말미암아, 속성의 특성에 알맞은 데이터 타입을 사용하지 못하고, 부정확하게 사용하는 경우를 자주 볼 수 있었습니다.
올바른 데이터 타입을 선정하는 것은 매우 중요합니다. 왜냐하면, 데이터 타입을 결정하면 다양한 제약조건이 만들어지고 데이터 타입을 변경하기 어렵기 때문(데이터 모델/타입을 변경하는 것은 큰 비용이 수반됩니다)입니다. 이뿐만 아니라, 질의(Query) 작성과 응용 프로그램의 성능에도 큰 영향을 미치게 됩니다(앞으로 이와 관련된 내용에 대해 알아보는 시간을 만들어 보겠습니다).
이 문서에서 현존하는 모든 DBMS에서 지원하는 데이터 타입을 다루는 것은 불가능합니다. 그러므로 ANSI SQL에서 요구하는 데이터 타입과 현재 많이 활용되는 Oracle, MS-SQL Server에서 지원하는 데이터 타입을 살펴보겠습니다. 이 문서에서 소개하지 않은 DBMS는 앞으로 기회가 되면, 이 문서에 추가하겠습니다.
ANSI SQL에서는 다음과 같은 데이터 타입을 포함하고 있습니다([SQL-92] Information Technology: Database Language SQL). 다양한 이유로 ANSI SQL의 버전이 꾸준히 갱신되면서 데이터 타입이 늘어나고 있습니다. 본 문서에서 다루는 데이터 타입은 일반적으로 자주 사용하는 데이터 타입만 소개하겠습니다. 참고로 ANSI SQL 버전별 특징과 지원하는 데이터 타입은 다음 링크(링크1, 링크2)에서 확인하실 수 있습니다.
CHARACTER(n) / CHAR(n) 고정 길이 문자열
CHARACTER VARYING(n) / VARCHAR(n) 가변 길이 문자열
NATIONAL CHARCTER(n) / NCHAR(n) 국제 문자셋을 지원하는 고정 길이 문자열
NATIONAL CHARACTER VARYING(n) / NVARCHAR(n) 국제 문자셋을 지원하는 가변 길이 문자열
* n은 자릿수를 의미
* 고정 길이 문자열의 경우에는 공백으로 채워짐.
INTEGER, SMALLINT, and ETC. 정수형
FLOAT, REAL, DOUBLE 실수형
NUMBER(precision, scale) / DECIMAL(precision, scale) 숫자형
* precision은 정밀도이며, scale은 소수점 이하 자릿수
DATE 일자 정보
TIME 시간 정보
TIME with TIME ZONE 해당 지역의 시간대 정보를 포함하는 시간 정보
TIMESTAMP DATE와 TIME의 결합 형식
TIMESTAMP with TIME ZONE 해당 지역의 시간대 정보를 포함하는 TIMESTAMP 정보
지금까지 ANSI SQL에서 지원하는 대표적인 데이터 타입에 관해 알아보았습니다. 이외에도 비트 정보를 관리하는 데이터 타입 등이 있습니다.
오라클에서 공식적으로 지원하는 데이터 타입은 22가지에 이릅니다. 앞 단락과 마찬가지로 모든 데이터 타입을 소개하지는 않고, 일반적으로 중요하다고 알려진 데이터 타입만 소개하겠습니다. 더 상세한 내용을 원하시면, 다음 링크에서 확인하실 수 있습니다.
이 데이터 타입을 설명하기 전에 알아둬야 할 개념이 있습니다. 아마도 Oracle 서적을 읽은 분이거나 활용하시는 분이라면 한 번쯤은 들어보셨을 것 같습니다. 바로 National Language Support(NLS)입니다. 자세한 내용은 다음 링크에서 확인하실 수 있으며, 간단히 정리하면 국가별 언어(데이터 정렬 규칙, 숫자 표현 형식, 원문 데이터의 인코딩 방법 등)를 지원하는 체계입니다.
CHAR(n) 고정 길이 문자열 (최대 2,000 바이트까지 저장 가능)
VARCHAR2(n) 가변 길이 문자열 (최대 4,000 바이트까지 저장 가능)
NCHAR(n) 국제 문자셋을 지원하는 고정 길이 문자열
NVARCHAR2(n) 국제 문자셋을 지원하는 가변 길이 문자열
* 일반 데이터 타입의 n은 바이트 수를 의미하며, 국제 문자셋은 자릿 수를 의미.
* 고정 길이 문자열의 경우에는 공백으로 채워짐.
앞 단락에서 살펴본 바와 같이 ANSI SQL에서는 다양한 숫자형을 지원합니다. 그러나 Oracle에서는 하나의 숫자형으로 ANSI SQL에서 요구하는 사양을 만족하고 있습니다. 물론 Oracle에서도 사용자의 편의를 위하여 INTEGER(INT), FLOAT 등의 표현 방법을 지원하지만, 내부적으로는 NUMBER 형식으로 변환하여 저장합니다. 그러므로 Oracle을 사용하실 때에는 NUMBER 형식을 정확히 사용하시는 것을 추천합니다.
NUMBER(precision, scale) 38자리 정밀도를 가진 숫자형
FLOAT(precision) NUMBER 데이터 형식의 서브 타입
* precision은 정밀도, scale은 소수점 이하 자릿수
Oracle에서도 ANSI SQL에서 소개하는 INTEGER 형식을 지원합니다(개인적인 의견으로 Oracle에서 사용하는 것을 추천하지는 않습니다). Oracle에서 INTEGER, FLOAT, NUMBER 형식을 사용해서 테이블을 생성할 때, 내부적으로 어떻게 생성되는지 알아보겠습니다.
CREATE TABLE t (
x INT PRIMARY KEY,
y INTEGER,
z FLOAT(10),
n NUMBER(10,2)
)
아주 간단한 테이블을 하나 생성했습니다. 이제 Oracle에서 제공하는 내장 패키지(DBMS_METADATA)를 활용하여, Oracle에서 내부적으로 테이블을 생성한 정의와 구문을 조회해보겠습니다.
SELECT dbms_metadata.get_ddl('TABLE', 'T')
FROM dual;
DBMS_METADATA 패키지를 활용하여 출력한 결과는 다음과 같습니다.
DBMS_METADATA.GET_DDL('TABLE','TMP')
---------------------------------------------------------------------------------------------------------------
CREATE TABLE "******"."TMP" (
"X" NUMBER(*,0),
"Y" NUMBER(*,0),
"Z" FLOAT(10),
"N" NUMBER(10,2),
PRIMARY KEY ("X")
USING INDEX PCTFREE 10 INITRANS 2 MAXTRANS 255 NOCOMPRESS LOGGING
TABLESPACE "USERS" ENABLE
) SEGMENT CREATION DEFERRED
PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 NOCOMPRESS LOGGING
TABLESPACE "USERS"
결과를 분석해보면, INTEGER와 INT는 NUMBER(*,0) 형식으로 만들어지며, FLOAT은 동일하게 FLOAT 형식으로 생성되는 것을 확인할 수 있습니다.
Oracle은 매우 다양한 시간/날짜 형식을 제공합니다. 일자 형식을 문자형으로 사용할지, 아니면 날짜형으로 사용할지에 대해 논란이 많습니다. 개인적인 의견이지만 기본적으로 특별한 응용의 요구사항을 제외하고, 속성의 의미가 날짜/시간 형식을 표현할 때에는 시간/일자 데이터 형식을 사용하는 것이 정확한 사용 방법이라고 생각합니다. 이 단락에서는 주로 활용하는 시간/날짜 데이터 형식을 소개하며, 더 자세한 내용은 다음 링크에서 확인하실 수 있습니다.
DATE 고정 길이 7바이트 DATE/TIME.
세기, 연도, 월, 일, 시간, 분, 초 표현
TIMESTAMP 고정길이 7 OR 11바이트(버전에 따라 다름).
DATE 타입과 유사하지만 초 단위를 소수점 9자리까지 표현 가능
TIMESTAMP with TIME ZONE 표준 시간대 정보를 저장하는 고정 길이 13바이트 TIMESTAMP
TIMESTAMP with LOCAL TIME ZONE DBMS 환경에 따라 표준 시간대 정보 결정.
고정 길이 7 OR 11바이트
INTERVAL YEAR TO MONTH 연과 월에 대한 기간 정보를 저장하며, 고정 길이 5바이트
INTERVAL DAY TO SECOND 일, 시, 분, 초의 기간 정보를 저장하며, 고정 길이 11바이트
마지막으로 대용량 객체를 표현하는 데이터 형식인 LOB에 대해 알아보겠습니다. 이 단락에서 LOB에 대해 자세한 내용을 다루는 것은 어렵습니다. LOB에 대해 자세히 알고 싶으신 분은 다음 링크를 참조하시면 도움을 받으실 수 있을 것입니다.
CLOB 문자 형식의 LOB. XML 또는 문자 정보를 대량으로 저장
NCLOB 국제 문자 형식을 지원하는 CLOB
BLOB 바이너리 형식의 LOB. 문서/이미지 등의 바이너리 정보 저장
BFILE 바이너리 파일 LOB
이상으로 Oracle이 지원하는 대표적인 데이터 형식을 알아봤습니다.
Microsoft SQL Server에서 지원하는 데이터 타입의 종류는 약 30개에 이릅니다. Oracle과 비교했을 때, 더 세분되어 구성된 것을 알 수 있습니다. Microsoft SQL Server에 대한 자세한 데이터 타입은 다음 링크에서 확인하실 수 있습니다.
CHAR(n) 고정 길이 문자열 (최대 8,000바이트까지 저장 가능)
VARCHAR(n) 가변 길이 문자열 (최대 8,000바이트까지 저장 가능)
NCHAR(n) 국제 문자 셋을 지원하는 고정 길이 문자열 (최대 8,000바이트까지 저장 가능)
NVARCHAR(n) 국제 문자 셋을 지원하는 가변 길이 문자열 (최대 8,000바이트까지 저장 가능)
* 일반 데이터 타입의 n은 바이트 수를 의미하며, 국제 문자셋은 자릿 수를 의미.
* 고정 길이 문자열의 경우에는 공백으로 채워짐.
BIT Boolean 타입으로 참(True), 거짓(False)에 사용
TINYINT 1 바이트 정수형. 0~255를 표현
SMALLINT 2 바이트 정수형. -32,768~32767을 표현
INT 4 바이트 정수형. 약 -21억~21억을 표현
DECIMAL(precision, scale) 5~17 바이트로 구성되며, 고정 정밀도와 배율을 가진 숫자형
* precision은 정밀도, scale은 소수점 이하 자릿수
DATE 고정 길이 3 바이트. 0001/01/01~9999/12/31 표현
TIME 고정 길이 5 바이트. 정확도는 100나노초까지 표현
DATETIME 고정길이 8 바이트. 1753/01/01~9999/12/31 표현하며, 정확도는 1/1000초
이상으로 Microsoft SQL Server에서 지원하는 대표적인 데이터 형식을 알아봤습니다.
지금까지 ANSI SQL과 대표적인 상용 DBMS에서 지원하는 데이터 타입에 대해 알아보았습니다. 여기서 소개한 데이터 타입 이외에도 DBMS별로 다양한 데이터 타입을 지원하고 있습니다. 앞에서도 간략히 설명했지만, 올바른 데이터 타입을 선택하는 것은 매우 중요합니다. 앞으로 DBMS를 선정하고 데이터 모델을 설계할 때, 데이터 타입을 제대로 숙지한 후 각 속성에 알맞은 데이터 타입을 선정하여 사용하는 것을 추천합니다.