오라클의 주요 데이터 형식
오라클의 데이터 형식은 크게 몇 가지 범주로 나눌 수 있다. 오라클이 기본적으로 제공하는 내장 데이터 형식(Oracle Built-in Data Types), ANSI 표준을 지원하거나 다른 DBMS와의 호환성을 위해 제공하는 형식, 그리고 사용자 정의 데이터 형식(User-Defined Types)이 있다. 우리는 오라클의 기본 내장 데이터 형식에 대해 집중적으로 살펴보자
오라클 내장 데이터 형식
오라클의 내장 데이터 형식은 크게 4가지로 분류할 수 있다.
- 문자(Character) 형식
- 숫자(Numeric) 형식
- 날짜(Date) 형식
- 대용량 객체(LOB) 형식
Character형식은 문자 데이터를 표현한다. 프로그래밍 언어에서는 큰따옴표(Double Quotation)를 사용하여 문자열을 정의하지만, 오라클에서는 작은따옴표(Single Quotation)를 사용하여 문자를 표현한다. 예를 들어, Oracle에서 문자는 'Hello'와 같이 작은따옴표로 감싸서 표현한다. 그래서 '148'은 숫자가 아닌 문자로 간주되고 "백사십팔"이 아니라 "일사팔"로 읽어야 한다. 또한, 오라클에서는 대소문자를 구분한다. 예를 들어, 'Hello'와 'hello'는 서로 다른 값으로 취급한다.
Numeric형식은 우리가 알고 있는 그대로, 숫자로만 표현된다.
Date 형식은 연도, 월, 일까지만 표현할 수 있는 형식이다. 예를 들어, '2024-08-29'는 날짜 형식으로 저장된다.
Timestamp 형식은 시, 분, 초까지 포함하여 시간 정보를 저장할 수 있는 형식이다. 예를 들어, '2024-08-29 14:30:00'와 같이 연월일과 시간까지 기록하는 경우이다. 만약 블로그 프로그램을 만들 때 글을 등록할 때의 시간을 기록하고 싶다면, 시간까지 저장할 수 있는 타임스탬프 형식을 사용하는 것이 적절할 것이다.
문자(Character) 형식
문자를 표현하는 자료는 크게 아래의 4가지가 존재한다.
CHAR
CHAR는 고정 길이 문자열 형식이다. 예를 들어, CHAR(10)이라고 정의하면, 10개의 문자를 저장할 수 있는 공간이 고정적으로 할당된다. 만약 10자 이하의 데이터를 저장해도 10자의 공간을 차지하게 되어 공간이 비효율적으로 사용될 수 있다. 예를 들어, ID와 같은 값이 고정된 길이를 가지지 않는 경우에는 적합하지 않고 전화번호나 생년월일에는 적합한 형식이라고 할 수 있다.
VARCHAR2
VARCHAR2는 가변 길이 문자열 형식이다. 예를 들어, VARCHAR2(500)이라고 정의하면 최대 500자까지 저장할 수 있지만, 실제 저장된 데이터가 2자라면 나머지 498자는 반환하게 되어 공간을 절약할 수 있다. 이 형식은 데이터 길이가 불규칙한 경우에 적합하며, 효율적인 메모리 관리를 위해 많이 사용된다.
하지만, 모든 문자열 데이터를 VARCHAR2로만 정의하는 것이 항상 최선은 아니다. 가변 길이 데이터는 내부적으로 구분자를 사용해 데이터를 구분하기 때문에, 검색 시 성능이 떨어질 수 있다. 반면, CHAR처럼 고정 길이 데이터를 사용하면, 데이터의 위치를 빠르게 계산할 수 있어 검색 성능이 더 우수하다. 즉, 고정 길이 데이터는 가급적 CHAR를 쓰는것이 바람직하고 가변 길이 데이터는 VARCHAR2로 쓰는것이 바람직하다.
※ VARCHAR2에 숫자 '2'가 붙는 이유는 오라클에서 VARCHAR2에 붙은 숫자 '2'는 다른 DBMS와의 차이점이다. 오라클은 향후 예약어로 사용할 가능성을 염두에 두고 이 표기를 유지하고 있다. 기능적으로는 VARCHAR와 동일하게 동작하지만, 오라클에서는 VARCHAR2를 사용하는 것이 권장된다.
NCHAR
NCHAR는 다국어 지원을 위한 고정 길이 유니코드 문자 형식이다. 영어, 한국어, 중국어 등 여러 언어의 문자를 저장할 수 있다. 기본적으로 UTF8 인코딩을 사용하며, 문자 하나를 저장하는 데 더 많은 바이트가 필요하다. 일반적으로 한 문자를 저장하는 데 최대 2~3바이트를 사용하는 단점이 있지만 다국어를 지원해야 하는 경우에는 NCHAR를 사용하는 것이 바람직하다.
NVARCHAR2
NVARCHAR2는 NCHAR와 VARCHAR2를 결합한 형식으로, 가변 길이 유니코드 문자 형식이다. 다국어 데이터를 가변 길이로 저장할 수 있어 다국어 지원이 필요한 경우에 유용하다.
기존 테이블 정의 검토
ID, PWD, NAME 컬럼
아래 그림의 테이블 정의를 보며 수정할 것이 있는지 확인해보자. 먼저 ID 컬럼은 VARCHAR2 형식으로 지정되어 있다. VARCHAR2는 가변 길이 문자열을 저장하는 데 적합하므로, ID, PWD, NAME에 사용하는 것이 적절하다. VARCHAR2(50)에서 숫자 50은 최대 길이를 의미하며, 실제 데이터의 길이만큼 공간을 사용하게 된다. 즉, 50자의 메모리 공간을 항상 차지하는 것이 아니라, 필요에 따라 유연하게 공간을 사용할 수 있다.
PHONE, BIRTHDAY 컬럼
PHONE 컬럼의 경우, 일반적으로 전화번호는 고정된 형식을 가지므로 CHAR 형식을 사용하는 것이 더 효율적일 수 있다. 예를 들어, 010-1234-5678 같은 형식은 13자로 고정되므로 CHAR(13)로 정의하는 것이 적절하다. 고정된 길이의 데이터를 다룰 때는 CHAR를 사용하여 검색 성능을 높일 수 있다. BIRTHDAY 컬럼도 마찬가지로, 날짜를 YYYY-MM-DD 형식으로 저장하는 경우 10자로 고정되므로 CHAR(10)으로 정의하는 것이 바람직하다.
GENDER 컬럼
GENDER 컬럼은 성별을 저장하기 위해 두 글자(예: 남성, 여성)를 저장하게 된다. 이 경우 CHAR를 사용하는 것이 적절하다. 그러나 CHAR(2)는 2개의 문자를 의미하는 것이 아니라, 2바이트를 의미한다. 오라클에서는 CHAR의 크기 단위가 기본적으로 바이트 단위로 설정되어 있어, 한국어와 같은 멀티바이트 문자는 글자 수와 바이트 수가 다를 수 있다. 만약CHAR(2)로 설정하고 한글 두 글자를 저장하려고 하면, 2바이트로는 부족하여 오류가 발생한다.
따라서 한글과 같은 멀티바이트 문자를 저장하려면 CHAR(4)와 같이 바이트 수를 고려하여 크기를 설정하거나, CHAR(2 CHAR)처럼 명시적으로 CHAR 단위를 설정하는 것이 좋다.
문자열의 길이와 저장 공간
직접 쿼리를 작성해가며 크기 단위에 대한 개념을 더욱 알아보자. "SELECT LENGTH('ab') FROM DUAL;"를 실행해보면 입력된 문자열의 문자 개수를 반환해주는 LENGTH 함수를 통해 문자열의 길이가 2라는 것을 확인할 수 있다.
문자의 개수가 아닌, 각 문자가 몇 바이트를 사용하는지 알고 싶을 때는 LENGTH 함수 뒤에 B를 붙여 LENGTHB 함수를 사용한다. LENGTHB 함수는 문자열의 바이트 길이를 반환해준다. "SELECT LENGTHB('ab') FROM DUAL;"를 실행해보면 영문자는 한 자가 1바이트라서 아래 그림처럼 2가 출력되는것을 확인할 수 있다.
이번에는 LENGTH 함수를 사용해 한글 문자의 개수를 확인해보자. 한글 문자열을 대상으로 LENGTH 함수를 실행하면 마찬가지로 입력된 문자의 개수를 반환한다. "SELECT LENGTH('한글') FROM DUAL;"를 실행하면 '한글'이라는 두 개의 한글 문자의 길이를 반환하여 2가 출력된다.
문자의 개수가 아닌, 문자열이 몇 바이트를 사용하는지 계산해주는 LENGTHB 함수를 사용해보자. "SELECT LENGTHB('한글') FROM DUAL;"를 실행시키면 6이 출력되며, 한글 한 글자가 3바이트씩 사용된것을 확인할 수 있다.
영문자를 제외한 각국의 언어, 즉 내셔널 문자는 한 글자가 몇 바이트를 사용하는지에 따라 저장 공간이 다르다. 중국어, 일본어, 한국어, 독일어 등 다양한 언어들은 대부분 3바이트를 사용한다.
내셔널 언어 지원 설정 확인
이러한 언어의 문자가 바이트를 얼마나 사용하는지 확인하려면, "SELECT * FROM NLS_DATABASE_PARAMETERS;"를 실행시켜 현재 데이터베이스의 환경 설정을 통해 내셔널 언어 지원 설정을 확인할 수 있다.
아래 그림의 빨간박스를 보면 "NLS_CHARACTERSET"이라는 파라미터가 AL32UTF8로 설정되어 있다. AL32UTF8은 UTF-8 인코딩 방식으로, 한글과 같은 멀티바이트 문자는 한 글자당 3바이트를 사용한다. 따라서, 만약 CHAR(2)라고 정의한 컬럼에 "남성"이나 "여성"과 같은 한글 데이터를 입력하려고 하면, 2바이트로는 공간이 부족하여 오류가 발생하게 된다. CHAR(2)는 2바이트를 의미하기 때문에, 한글 한 글자조차 들어갈 수 없게 된다. 이 점을 고려하여 데이터 타입을 적절하게 선택해야 한다.
위에서 배웠던 내용을 토대로 테이블을 재정의 하기 위해서 DROP TABLE MEMBER;를 실행시켜 이전에 작성했던 테이블을 삭제하자.
아래 그림의 쿼리를 토대로 테이블을 재생성해보자.
GENDER 컬럼은 CHAR(2)로 정의되어 있다. "INSERT INTO MEMBER(GENDER) VALUES('남성');" SQL을 사용하여 GENDER에 '남성'이라는 값을 삽입해보자. 하지만 "열에 대한 값이 너무 큼"이라는 오류가 발생한다. 이 오류는 GENDER 컬럼이 CHAR(2)로 설정되어 있어 최대 2바이트만 저장할 수 있는 상태에서, '남성'이 6바이트를 차지하기 때문에 발생한 것이다. 따라서 GENDER 컬럼을 CHAR(6)으로 수정하여 6바이트까지 저장할 수 있도록 해야 한다.
저장공간을 CHAR(size)로 설정하는것 외에 CHAR 타입 뒤에 (size [BYTE | CHAR]) 옵션을 추가하여 바이트 단위 또는 문자 단위로 저장 공간을 지정할 수도 있다. CHAR(size BYTE)는 기본 값으로, 크기가 바이트 단위로 설정된다. CHAR(size CHAR)는 크기를 문자 단위로 설정한다. 예를 들어, CHAR(3 CHAR)는 3문자, 즉 한글과 같은 멀티바이트 문자도 3글자까지 저장할 수 있다. GENDER CHAR(2 CHAR)로 정의하면 '남성'과 같은 두 글자를 저장할 수 있게 된다.
다시 테이블을 DROP하고 수정된 테이블을 다시 만들어보자. 그 다음 INSERT INTO MEMBER(GENDER) VALUES('남성');를 실행해보면 이전에는 오류가 발생하였지만 정상적으로 삽입되는것을 확인할 수 있다.
"SELECT LENGTHB(GENDER) FROM MEMBER;"을 실행시켜 출력결과를 확인해보면 "남성"이라는 6바이트 데이터가 CHAR(2 CHAR)를 통해 제대로 삽입된 것을 확인할 수 있다. 즉 영문자나 숫자는 기본적으로 1바이트만 사용하기 때문에 이러한 옵션이 필요 없지만, 한글이나 다른 각국의 언어는 멀티바이트를 사용하므로 이 옵션이 없으면 공간이 부족하게 된다.
하지만 한글이나 다른 각국의 언어를 지원하기 위해 CHAR 타입에 (size CHAR) 옵션을 추가하는 것은 바람직하지 않은 방법이다. 각국의 언어를 지원하기 위한 더 적합한 데이터 타입인 NCHAR이 존재하기 때문이다.
"SELECT * FROM NLS_DATABASE_PARAMETERS;"를 실행시켜 다시 오라클 데이터베이스의 환경 설정을 확인해보면 NLS_CHARACTERSET은 AL32UTF8로 설정되어 있는데 이것은 UTF-8 인코딩 테이블의 32비트 버전을 사용한다는 의미이다. UTF-8은 각 문자에 최대 3바이트를 사용하여 각국의 언어를 지원한다.
반면, NLS_NCHAR_CHARACTERSET은 AL16UTF16으로 설정되어 있으며 이것은 UTF-16 인코딩 방식을 사용한다. UTF-16은 문자 하나를 저장하는 데 기본적으로 2바이트를 사용한다. 따라서 NCHAR와 같은 내셔널 문자 데이터 타입을 사용하면 멀티바이트 문자를 보다 효율적으로 저장할 수 있다. 예를 들어, '한'이라는 한 글자는 2바이트만으로 표현이 가능하게 된다.
따라서 한글과 같은 멀티바이트 문자를 저장할 때 GENDER CHAR(2 CHAR) 보다는 GENDER NCHAR(2)가 더 효율적이고 공간절약에 유리하다. 그러면 다시 "DROP TABLE MEMBER"를 실행하여 테이블 한번 삭제하고 아래 그림의 CREATE문을 실행해보자.
그리고 다시 GENDER 컬럼에 '남성' 데이터를 다시 삽입하고 이 데이터가 얼마나 많은 바이트를 사용하는지 확인해보자. 실행 결과, GENDER 컬럼에 저장된 '남성' 데이터는 4바이트를 사용한다 이것은 NCHAR가 UTF-16 인코딩 방식을 사용하여 각 문자가 2바이트를 차지하기 때문이다. 따라서 한글과 같이 다국어 문자를 지원하는 경우에는 NCHAR를 사용하는 것이 데이터 저장 효율성 측면에서 더 나은 선택이다.
이제 위에서 배웠던 내용을 토대로 다시 한번 재검토를 해보자.
ID 컬럼은 영문, 숫자로 이루어질 가능성이 높고 다국어가 들어갈 필요가 없기 때문에 VARCHAR2로 충분해서 굳이 NVARCHAR를 사용할 필요가 없다. NAME 컬럼 같은 경우 다국어 이름이 들어갈 가능성이 있으므로 NVARCHAR2를 사용하는 것이 더 적절하다. PWD 컬럼은 비밀번호는 보통 영문자와 숫자, 특수문자 조합으로 구성되기 때문에 VARCHAR2가 적합하다. BIRTHDAY 컬럼은 생년월일은 날짜 형식으로 고정된 형식이므로 CHAR로 설정하는 것이 바람직하다. PHONE 컬럼도 마찬가지로 전화번호 역시 숫자와 기호로 이루어져 있으므로 CHAR로 설정하는 것이 적절하다.
이제 테이블을 다시 삭제하고 최종 테이블을 생성하면 된다.
※ 테이블에 데이터가 없는 상태라면 생성과 삭제를 반복해도 되지만 데이터가 존재한다면 ALTER를 사용해야한다.
최대 크기 설정
기본적으로 오라클의 환경 설정에서는 MAX_STRING_SIZE가 STANDARD로 설정되어있다. 이 경우 CHAR, VARCHAR2, NCHAR, NVARCHAR2의 최대 크기는 4,000바이트이다.
EXTENDED 설정 시 최대 32,767바이트를 사용할 수 있지만 이 설정은 일반적인 테이블 컬럼에 사용하기에는 권장되지 않는다. 문자형 데이터 타입의 한계를 넘는 데이터, 예를 들어 대량의 텍스트 데이터(아티클, 블로그 포스트 등)가 필요한 경우에는 LOB (Large Object) 타입을 사용하여 보다 큰 데이터를 다룰 수 있다.
큰 문자열(Character) 형식
데이터베이스에서 아티클 작성과 같이 큰 문자열을 다뤄야 할 때는 LONG, CLOB, NCLOB와 같은 문자형 데이터타입을 사용할 수 있다. 이러한 데이터 타입들은 일반적인 문자열 데이터 타입의 한계를 넘는 대용량 데이터를 처리할 수 있도록 설계되어있다.
LONG
LONG 타입은 최대 2GB까지의 가변 길이 문자열을 저장할 수 있는 데이터 타입이다. 예전에는 대용량 데이터를 처리하기 위해 사용되었지만, 현재는 잘 사용되지 않는다. 제약사항으로는 한 테이블에서 LONG 컬럼은 단 하나만 사용할 수 있으며, 다른 LONG 컬럼을 추가할 수 없다. 그래서 이러한 LONG타입은 여러 제약사항이 있어, 현재는 CLOB이 LONG을 대체하고 있다.
CLOB (Character Large Object)
CLOB는 대용량 텍스트 데이터를 처리하기 위한 데이터 타입으로, 최대 4GB까지의 데이터를 저장할 수 있다. 일반적인 문자 데이터와 달리, 매우 큰 텍스트를 저장할 수 있기 때문에 아티클, 웹 콘텐츠 등 많은 데이터를 담을 수 있는 컬럼에 적합하다. CLOB는 여러 개의 컬럼에 사용할 수 있다.
NCLOB (National Character Large Object)
NCLOB는 CLOB와 유사하지만, 유니코드를 지원하는 내셔널 문자 데이터 타입이다. UTF-16 인코딩을 사용하여 각국의 언어를 포함한 대용량 텍스트 데이터를 저장할 수 있다. 최대 4GB까지의 데이터를 저장할 수 있어, 다국어 지원이 필요한 대용량 텍스트 컬럼에 적합하다.
따라서 대용량 텍스트 데이터를 저장할 때는 CLOB과 NCLOB을 사용하는 것이 바람직하다.
참고자료
[1] 유튜브 채널 뉴렉처 - 오라클 데이터 형식 #1 (문자 형식)
'💾 Database > Oracle' 카테고리의 다른 글
[오라클] 7.ALTER(수정, 삭제, 추가) (0) | 2024.08.31 |
---|---|
[오라클] 6.SQL 데이터 타입(숫자형) (0) | 2024.08.31 |
[오라클] 4.사용자 계정, 데이터베이스, 테이블 생성 (0) | 2024.08.27 |
[오라클] 3.PDB 서버 접속 (0) | 2024.08.25 |
[오라클] 2.SQL Developer 설치하기 (0) | 2024.08.24 |