저장 방식이 뭔지도 모르겠고, 다국어 지원이랑 저장 방식이 무슨 상관이 있는지도 모르겠는 사람 주목.. 🫠 바로 접니다…
MSSQL에서 PostgreSQL로 Database를 마이그레이션할 일이 생겨서 데이터 타입을 알아보던 중 생긴 의문이 생겼습니다.
- PostgreSQL에서 varchar(n)과 text는 무슨 차이?
- MSSQL에서 nvarchar(n)와 varchar(n)는 또 무슨 차이고?
- 다국어 지원을 위해서... 어떤 걸 써야 된다는 거야?
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은 두 가지를 결정함.
- 문자 집합(Charset) → 어떤 문자들을 저장할 수 있는가?
- 정렬 및 비교 방식 → 대소문자 구분 여부, 정렬 방식
📌 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는 공간 낭비가 커서 거의 사용되지 않음
'공부기록 > 여러가지' 카테고리의 다른 글
[MongoDB] 중복 문서 제외하고 bulkWrite하기 (createIndex 사용) (0) | 2023.07.14 |
---|---|
mssql server 복원시 오류 Restore failed for Server '*'. (Microsoft.SqlServer.SmoExtended) (0) | 2023.06.29 |
MongoDB 시작하기(Enterprise vs Community Edition 차이) (0) | 2023.06.27 |
PostgreSQL DBMS 추천 및 DBeaver로 시작하기(설치) (0) | 2023.06.25 |
SNAKE TO CAMEL/CAMEL TO SNAKE CONVERTER 온라인 변환기 (0) | 2023.03.07 |