문자 데이터 타입

문자 데이터 타입

PostgreSQL에서 문자열을 다루는 타입은 크게 character varying, character, text 세 가지예요. 이름이 비슷해서 헷갈리기 쉬운데, 실제 동작은 "길이 제한이 있느냐"와 "공백을 어떻게 다루느냐"에 따라 갈려요. 그래서 상황에 맞는 타입을 고르는 게 중요해요.

출처: PostgreSQL 공식 문서 — Character Types

본문

세 가지 기본 문자열 타입

SQL 표준은 두 가지 주요 문자 타입을 정의해요. character varying(n)(줄여서 varchar(n))과 character(n)(줄여서 char(n))이에요. 여기서 n은 양의 정수로, 두 타입 모두 최대 n 문자(바이트가 아니라 문자)까지 문자열을 저장할 수 있어요.

차이는 저장할 때 드러나요. 저장할 문자열이 선언된 길이보다 짧으면, character 타입은 공백으로 채워서 고정 길이로 저장해요. 반면 character varying은 짧은 문자열을 그대로, 길이를 늘리지 않고 저장하죠.

여기에 더해 PostgreSQL은 길이 제한이 없는 text 타입을 제공해요. text는 SQL 표준 타입은 아니지만 여러 DBMS가 비슷한 타입을 갖고 있답니다. 사실 text가 PostgreSQL의 네이티브 문자열 타입이라서, 문자열을 다루는 대부분의 내장 함수는 character varying이 아니라 text를 받거나 반환하도록 정의돼 있어요.

별칭과 길이 규칙

varcharcharacter varying의 별칭이고, bpchar(길이 지정과 함께)와 charcharacter의 별칭이에요. varcharchar는 SQL 표준에 정의된 별칭이고, bpchar는 PostgreSQL 확장이에요.

길이 n을 지정하면 0보다 커야 하고 10485760을 넘을 수 없어요. character varying(혹은 varchar)을 길이 지정 없이 쓰면 어떤 길이의 문자열이든 받아들여요. bpchar도 길이 지정이 없으면 어떤 길이든 받지만, 뒤쪽 공백은 의미적으로 무시돼요. character(혹은 char)에 길이를 지정하지 않으면 character(1)과 동일해요.

공백 처리의 핵심

character 타입의 값은 지정된 폭 n만큼 물리적으로 공백으로 채워져 저장되고, 그렇게 표시돼요. 그런데 뒤쪽 공백(trailing space)은 의미적으로 무시되고, 두 character 값을 비교할 때는 공백을 감안하지 않아요. 반대로 textcharacter varying은 뒤쪽 공백을 의미 있는 값으로 취급해요. 그래서 'a''a '를 비교할 때 타입에 따라 결과가 달라질 수 있으니 주의해야 해요.

저장 용량

짧은 문자열(최대 126바이트)의 저장 요구량은 실제 문자열에 1바이트가 더해진 크기예요. character의 경우 공백 패딩도 포함해요. 더 긴 문자열은 오버헤드가 1바이트가 아니라 4바이트예요. 긴 문자열은 시스템이 자동으로 압축해서 디스크에 저장되는 물리적 크기가 더 작을 수 있어요. 매우 긴 값은 배경 테이블에 저장되어 짧은 컬럼 값에 대한 빠른 접근을 방해하지 않게 해요. 어쨌든 저장할 수 있는 가장 긴 문자열은 약 1GB 정도예요.

어떤 타입이 좋을까

다른 DBMS에서는 character(n)이 성능상 이점이 있는 경우도 있지만, PostgreSQL에서는 그런 이점이 없어요. 오히려 character(n)은 추가 저장 비용 때문에 세 가지 중 대개 가장 느려요. 대부분의 상황에서는 textcharacter varying을 쓰는 게 좋아요. 명시적으로 특정한 상한이 없는 긴 문자열을 저장하고 싶다면, 임의의 길이 제한을 만드는 대신 text나 길이 지정 없는 character varying을 쓰는 게 낫답니다.

내부용 특수 타입

두 가지 다른 고정 길이 문자 타입이 있는데, 이건 일반 용도가 아니라 내부 시스템 카탈로그에서만 쓰여요. name 타입은 식별자를 저장하는 데 쓰이고, 현재 길이는 64바이트(63개의 사용 가능한 문자와 종결자)예요. "char"(따옴표 포함)는 char(1)과 달리 저장 공간이 1바이트만 쓰고, 그래서 단일 ASCII 문자만 저장할 수 있어요. 시스템 카탈로그에서 단순한 열거형으로 사용하죠.

이런 제약 때문에 "너무 긴 값을 넣으면" 아래처럼 오류가 나요. 명시적으로 잘라서 넣으면 오류 대신 잘린 값이 저장되는 것도 볼 수 있어요.

ERROR:  value too long for type character varying(5)
INSERT INTO test2 VALUES ('too long'::varchar(5)); -- explicit truncation
SELECT b, char_length(b) FROM test2;
   b   | char_length
-------+-------------
 ok    |           2
 good  |           5
 too l |           5

더 알아보기