본문 바로가기
공부기록/여러가지

PostgreSQL varchar(n) vs. text (feat. MSSQL nvarchar(n) vs. varchar(n))

by 책읽는 개발자 ami 2025. 2. 12.
728x90
반응형

저장 방식이 뭔지도 모르겠고, 다국어 지원이랑 저장 방식이 무슨 상관이 있는지도 모르겠는 사람 주목.. 🫠 바로 접니다…

MSSQL에서 PostgreSQL로 Database를 마이그레이션할 일이 생겨서 데이터 타입을 알아보던 중 생긴 의문이 생겼습니다.

  1. PostgreSQL에서 varchar(n)과 text는 무슨 차이?
  2. MSSQL에서 nvarchar(n)와 varchar(n)는 또 무슨 차이고?
  3. 다국어 지원을 위해서... 어떤 걸 써야 된다는 거야?

PostgreSQL에서 varchar(n)과 text는 무슨 차이?

타입 설명 저장 방식
 `varchar(n)` 가변 길이 문자열 UTF-8
 `text` 무제한 길이 문자열 UTF-8

결론부터 말씀 드리면, 큰 차이는 없습니다.

✅ PostgreSQL은 모든 문자열이 기본적으로 UTF-8로 저장합니다.

확인하고 싶으시면 sql 창에서 아래 명령문을 날려보세요!

SHOW SERVER_ENCODING;

✅ varchar(n)에서 n이 있는 경우, 글자수 제한을 둡니다.

✅ 만약 varchar라고만 쓴다면? text랑 동일하게 동작합니다.

📌 다만, MSSQL, MySQL, Oracle 등 여러 Database를 지원해야 하는 저희 회사의 경우엔 통일성을 위해 varchar(n)을 쓰기로 했습니다.

📌 참고로 postgreSQL에서 varchar(n)의 n은 byte가 아니라 글자수 입니다!

예를 들어, 영어는 1 byte, 한글은 3 byte, 이모지는 4 byte이지만 byte와 상관없이 모두 n자까지 저장할 수 있는 셈이죠. (byte로 관리하고 싶다면 bytea 타입을 사용하면 됩니다)

MSSQL에서 nvarchar(n)와 varchar(n)는 또 무슨 차이고?

타입 설명 인코딩 방식
 `VARCHAR(n)` 가변 길이 문자열 (1~8000 byte) Collation에 따라 결정됨
(예: Korean_Wansung_CI_AS는 euc-kr 계열)
 `NVARCHAR(n)` 가변 길이 유니코드 문자열 (1~4000 글자) UTF-16 사용
(N'문자열' 형식 필요)

일단 본인이 사용하는 SQL 서버의 Database가 어떤 Collation 인지 확인을 해봐야 합니다.

SELECT collation_name FROM sys.databases WHERE name = DB_NAME();

참고로 전 `Korean_Wansung_CI_AS` 이렇게 나오더라구요. 즉, `varchar`에서 `UTF-8`을 지원하지 않는다는 의미입니다.

(`Latin1_General_100_CI_AS_SC_UTF8` 와 같이 `_UTF8`이 포함되어 있어야지 `varchar`에서 `UTF-8`을 지원합니다)

✅ 결론적으로, `nvarchar`를 써야 합니다. 현재 제 설정 상으로는 `varchar`는 byte로 저장하기 때문에 다국어 지원하기엔 부족해 보입니다. 

✅ 예를 들어, varchar(3)에 ‘ABC’는 저장할 수 있지만 ‘가나다’를 저장하면 오류가 발생합니다. ‘가나다’는 총 6 byte이기 때문이죠.

 

⚠️ 문자를 저장할 때 N'입력할 문자' 이런 식으로 `N`을 붙여줘야 합니다.

MSSQL에서 `NVARCHAR`는 `Unicode(UTF-16)`를 저장하는 타입이고,

`VARCHAR`는 Collation(예: Korean_Wansung_CI_AS) 기반으로 인코딩이 결정됩니다.

즉, `NVARCHAR`에 저장하려면 입력 값도 반드시 Unicode(UTF-16) 형식이어야 한다는 의미죠.

DECLARE @str NVARCHAR(10);
DECLARE @str2 NVARCHAR(10);
SET @str = '한글';
SET @str2 = N'한글';

 

위 코드 중 `@str`는 암묵적으로 `VARCHAR`로 변환된 후 `NVARCHAR`로 저장되므로 문자 손실(깨짐) 가능성이 있습니다.

반면, `@str2`처럼 N을 붙이면 Unicode로 직접 저장되므로 손실이 발생하지 않습니다.

 

👥 안 깨지던데요?

맞습니다. 항상 손실이 발생하는 것이 아니라, 현재 시스템의 Collation이 지원하는 문자가 아닐 때만 문제가 발생합니다.

한 번 이모지를 한 번 입력해보십쇼.. 그러면 이모지 대신, `??` 이렇게 저장되는 걸 확인할 수 있습니다.

반면 N‘💖’ 이렇게 쓰면 안 깨지고 잘 들어가는 걸 확인할 수 있죠!

 

다국어 지원을 위해서... 어떤 걸 써야 된다는 거야?

제가 내린 결론은 아래 표와 같습니다.

MSSQL  nvarchar(n)
PostgreSQL varchar(n), text 둘 다 가능

 

💡 Collation이 무엇인지 궁금하다면 `더보기`를 확인해 주세요!

더보기

Collation = 정렬 및 비교 규칙 (문자 집합 + 정렬 방식 포함)

데이터베이스에서 문자를 처리할 때, Collation은 두 가지를 결정함.

  1. 문자 집합(Charset) → 어떤 문자들을 저장할 수 있는가?
  2. 정렬 및 비교 방식 → 대소문자 구분 여부, 정렬 방식

📌 MSSQL에서는 Collation 이름의 의미는 아래와 같다.

Korean_Wansung_CI_AS

[문자집합]_[언어]_[정렬규칙]

Korean_Wansung=문자집합 및 언어 설정(완성형 한글)

CI=Case Insensitive 대소문자 구분 안 함. A=a (반대는 CS)

AS=Accent Sensitive 악센트 구분 함 é ≠ e (반대는 AI)

💡 UTF-8 ? UTF-16이 궁금하다면 `더보기`를 확인해주세요

더보기

Unicode 문자를 실제 파일이나 데이터베이스에 저장할 때는 Encoding(인코딩) 방식이 필요함.

인코딩 방식 설명 한글 저장 시 특징

UTF-8 가변 길이(1~4 byte) 3 byte/글자 영어는 1 byte, 한글은 3 byte
UTF-16 고정 길이(2 byte 또는 4 byte) 2 byte/글자 대부분 2 byte지만 일부 문자는 4 byte
UTF-32 고정 길이(4 byte) 4 byte/글자 모든 문자 4 byte, 비효율적

 UTF-8은 저장 공간을 절약할 수 있음

 UTF-16은 동아시아 문자(한글, 중국어, 일본어) 처리 속도가 빠를 수 있음

 UTF-32는 공간 낭비가 커서 거의 사용되지 않음

728x90
반응형