Spring JPA 를 통해 DB에 테이블을 만들고 컬럼으로 HashMap 을 지정할 경우 어노테이션을 통해서 따로 추가적인 정의를 해줘야 한다. 실제 실무에서 사용되는 코드를 살펴보던 중 Map<Integer, String> 타입의 데이터를 저장하는 테이블을 발견했는데 컬럼의 정의가 "nvarchar"로 정의되어 있었다.
나는 그 이유가 bulk insert를 위한 명시적 columnDefinition 인 줄 알았으나 잘못 된 생각이었다.
우선 varchar와 nvarchar 의 차이를 살펴보자.
varcher | nvarchar | |
형태 | 가변길이 문자열 저장 | |
영어 | 1byte | 2byte |
한글 | 2byte | |
인코딩 | iso_1 | 유니코드 |
둘의 중요한 차이는 인코딩 방식이 다르다는 것이다.
컴퓨터의 기본 저장 단위는 1바이트로 8bit를 사용하게 된다. 우리가 흔히 잘 알고있는 아스키 코드는 8비트를 사용하는 인코딩 방식인데 실제로 1비트는 통신에러 검출을 위한 비트이기 때문에 1비트를 제외한 7비트를 통해 인코딩을 진행하게 된다. 하지만 아스키 코드를 통해서 모든 문자가 표현되지 않으니 통신에서 검출을 위한 1비트 까지 인코딩을 포함시킨 방식인 ANSI 코드가 등장했다. 그럼에도 불구하고 중국의 수많은 한자, 그리고 한글 등 더 많은 다양한 문자를 표현하기에는 역부족이었기 이를 해결하기 위해 등장한 인코딩 방식이 유니코드 방식이다.
유니코드 방식은 2바이트를 사용하여 수 많은 문자를 표현할 수있다. 처음보는 독특한 형태부터 우리가 알고있는 모든 문자를 담을 수 있도록 하는 인코딩 방식이다.
처음으로 되돌아 가서 columnDefinition에 nvarchar로 정의했던 이유는 바로 이 유니코드를 담기 위해서였다.