개요

nvarchar와 nchar를 사용할 때 n이 곧 문자 개수라고 가정하는 경우가 많음 하지만 SQL Server에서 nchar(n), nvarchar(n)의 n은 문자 개수가 아니라 2바이트 단위의 길이, 즉 바이트 페어(byte-pair) 개수로 정의됨 문자 집합 범위에 따라 한 문자가 1개 혹은 2개의 바이트 페어를 사용할 수 있어 저장 가능한 문자의 실제 개수는 달라짐

핵심 개념과 정의

  • nchar(n), nvarchar(n)의 n은 0~4000 바이트 페어 범위의 길이 의미
  • 하나의 바이트 페어는 2바이트로, 내부적으로 UTF-16 코드 유닛 단위로 이해 가능
  • 유니코드 BMP 범위(0~65,535) 문자는 보통 1 바이트 페어 사용
  • 보조 평면 범위(65,536~1,114,111) 문자는 서러게이트 페어로 2 바이트 페어 사용
  • 따라서 n이 문자의 최대 개수를 보장하지 않음
  • char(n), varchar(n)은 n이 바이트 수 의미라는 점에서 유사한 맥락이나, nvarchar/nchar는 바이트 페어 기준이라는 차이 존재

추가 기본값 규칙

  • n을 명시하지 않고 데이터 정의나 변수 선언을 하면 기본 길이 1 적용
  • CAST에서 n을 생략하면 기본 길이 30 적용

크기 선택 가이드

  • nchar 고정 길이 데이터에 적합
  • nvarchar 가변 길이 데이터에 적합
  • nvarchar(max) 길이가 4000 바이트 페어를 초과할 가능성이 있는 경우 선택

그 밖의 타입과 옵션

  • sysname은 null 불가 nvarchar(128)과 동등하며 데이터베이스 오브젝트 이름에 사용
  • nchar, nvarchar 컬럼은 COLLATE로 별도 지정하지 않으면 데이터베이스 기본 콜레이션 상속
  • nchar, nvarchar에는 SET ANSI_PADDING이 항상 ON으로 적용, OFF는 무효

문자열 리터럴과 N 프리픽스

  • 유니코드 문자열 리터럴은 항상 N 접두사를 붙여 NVARCHAR로 해석되게 표시 권장
  • N 없이 작성하면 데이터베이스의 기본 코드 페이지로 변환되어 일부 문자가 손실될 수 있음
  • SQL Server 2019 이후 UTF-8 사용 가능 콜레이션을 적용하면 기본 코드 페이지가 UTF-8을 지원하여 char/varchar에서도 유니코드 저장 가능하지만, nvarchar/nchar 사용 시에는 여전히 N 접두사 관용 유지 권장
  • SC 콜레이션 사용 여부에 따라 내부적으로 UCS-2 또는 UTF-16 경로로 처리되므로 혼동 방지를 위해 N 접두사 일관 사용이 안전

동작 원리와 저장 구조

  • nvarchar는 논리적으로 UTF-16 코드 유닛 단위 저장
  • BMP 문자는 1 코드 유닛, 보조 평면 문자는 2 코드 유닛 필요
  • nvarchar(n)에서 n은 코드 유닛 2개 묶음인 바이트 페어 개수로 취급되므로, n 범위 내에서 BMP 문자 위주면 더 많은 문자를 담을 수 있고 이모지 같은 보조 평면 문자가 섞이면 같은 n에서도 저장 가능한 문자 수가 줄어듦
  • 예시로 nvarchar(10) 컬럼에 BMP 문자만 저장하면 최대 10자 가능하지만, 보조 평면 문자가 포함되면 10자보다 적게 저장됨

사용 시 주의와 베스트 프랙티스

  • 설계 단계에서 길이 제약을 문자 수가 아닌 저장 단위로 모델링할 것
    • 사용자 입력에서 문자 수 제한을 걸 때에도 저장 실패나 잘림 방지 위해 코드 유닛 기준 검증 권장
  • 길이 n은 0~4000 바이트 페어 범위 내에서 선택, 더 크면 nvarchar(max) 고려
  • nchar는 패딩 특성으로 고정 길이 정렬과 일정한 저장 패턴이 필요한 경우 유리하지만 불필요한 저장 공간 증가 가능
  • nvarchar는 길이 변동이 큰 일반 텍스트에 적합, 인덱스 키 길이 제한 고려 필요
  • 문자열 리터럴에는 N 접두사 습관화, 특히 다국어와 이모지 처리 환경에서 데이터 손실 예방
  • COLLATE로 UTF-8을 사용할지, UTF-16 계열인 nvarchar를 표준으로 삼을지 일관된 전략 수립
  • ANSI_PADDING은 nchar/nvarchar에 항상 ON이라는 점을 전제로 길이와 패딩 규칙 이해 필요

간단 예시

  • N 접두사 유무 차이 확인
-- 유니코드로 의도 표현
SELECT N'가나다', N'😀'

-- 접두사 없이 작성 시 데이터베이스 기본 코드 페이지에 따라 손실 가능
SELECT '가나다', '😀'
  • 저장 단위와 길이 함수 차이 확인
-- LEN은 문자 길이, DATALENGTH는 바이트 길이 반환
SELECT LEN(N'가😀') AS char_len
     , DATALENGTH(N'가😀') / 2 AS byte_pairs
  • nvarchar(10)에서 보조 평면 문자가 차지하는 저장 단위로 인해 문자 수가 10 미만이 될 수 있음

요약

  • nvarchar, nchar의 n은 문자 수가 아닌 바이트 페어 수 의미
  • BMP 문자는 1 바이트 페어, 보조 평면 문자는 2 바이트 페어 사용
  • n 미지정 시 기본값은 정의문/선언에서 1, CAST에서는 30
  • nchar는 고정 길이, nvarchar는 가변 길이, nvarchar(max)는 4000 바이트 페어 초과 가능성 대응
  • sysname은 null 불가 nvarchar(128) 동등 타입
  • 콜레이션 미지정 시 데이터베이스 기본 콜레이션 적용, ANSI_PADDING은 항상 ON
  • 유니코드 리터럴은 N 접두사 사용 권장, UTF-8 콜레이션 사용 시에도 일관성 유지가 안전

참고자료

  • 공식 문서에서 nchar, nvarchar 길이 정의 및 기본값, 콜레이션과 저장 차이 확인 권장

참고자료