헤르메스 LIFE

[MSSQL] 다국어(한글) 문제 본문

Database

[MSSQL] 다국어(한글) 문제

헤르메스의날개 2021. 5. 22. 10:44
728x90

개발환경

Spring 4.x

MyBatis

MSSQL 2019

MSSQL Database를 잘 몰라서 엄청 고생 중입니다.

결론은 "한글을 사용한다면, Collation 을 무조건 'Korean_Wansung_CI_AS' 으로 사용하라." 입니다.

DBCP 설정은 "sendStringParametersAsUnicode=false" 를 사용해야 합니다.

Database의 Collation 을 "Korean_Wansung_CI_AS" 로 설정 후 "sendStringParametersAsUnicode=false" 를 사용해야 합니다.


"sendStringParametersAsUnicode=false" 를 사용해야 하는 이유

1. VARCHAR DATA TYPE을 MSSQL 내부적으로 NVARCHAR로 변환하면서 CPU를 과도하게 사용하는 문제가 있다고 합니다. 데이터가 많아지면 CPU 100% 도 문제 없습니다.

2. Mybatis에서 전달되는 Parameter가 NVARCHAR로 전달 되면서 WHERE 절에 걸리는 조건절이 INDEX를 타지 않습니다.

※ 주의점

1. Collation 이 "SQL_Latin1_General_CP1_CI_AS" 로 설정되어 있는 경우 "sendStringParametersAsUnicode=false" 를 사용하면 한글 등록 시 물음표("?") 로 저장됩니다.

2. Collation 이 "Korean_Wansung_CI_AS" 이더라도, Server Collation 이 "SQL_Latin1_General_CP1_CI_AS" 인 경우 Temp Table 생성 시 "SQL_Latin1_General_CP1_CI_AS" 로 생성됩니다.


select serverproperty('collation')

위 쿼리의 결과가 "SQL_Latin1_General_CP1_CI_AS" 라면 서버를 다시 설치하는게 빠릅니다.

DB생성 후 데이터 이관을 했다거나.. 그럼.. 불행이도..

설치만 했다면 SQL Server COLLATION 을 변경하기 위해 아래의 명령을 실행하면 됩니다.

※ 반드시 백업하세요. 완전 초기화 됩니다.

C:\Program Files\Microsoft SQL Server\120\Setup Bootstrap\SQLServer2014>
                           2008 이라면 100
                           2014 이라면 120
                           2016 이라면 130
                           2017 이라면 140
                           2019 이라면 150

Setup /QUIET /ACTION=REBUILDDATABASE /INSTANCENAME=MSSQLSERVER /SQLSYSADMINACCOUNTS=[Admin계정]  /SAPWD=[Admin패스워드] /SQLCOLLATION=Korean_Wansung_CI_AS

SQL Server JDBC Driver 는 String type의 파라메터를 기본적으로 NVARCHAR로 매핑합니다. ( SQL Management 에서는 괜찮습니다. )

https://woowabros.github.io/study/2019/01/25/sqlserver-jdbc-driver.html

 

SQL Server 에게 String 이란? (NVARCHAR 인가 VARCHAR 인가) - 우아한형제들 기술 블로그

SQL Server JDBC Driver 를 사용하면서 배운, 그리고 주의해야 할 특징

woowabros.github.io

https://oingdaddy.tistory.com/137

 

MSSQL에서 DataType Issue 성능개선 (VARCHAR type의 NVARCHAR type으로의 형변환 문제)

성능테스트를 할때 이슈가 발생을 하였다. 성능이 생각만큼 나오지 않아서 원인을 찾다가 한가지 흥미로운 사실을 발견했다. MSSQL은 DataType에 따라서 우선순위가 존재하는데 NVARCHAR가 VARCHAR보다

oingdaddy.tistory.com

 

sendStringParametersAsUnicode 속성을 "true"로 설정하면 문자열 매개 변수가 유니코드 형식으로 서버에 전송됩니다.
sendStringParametersAsUnicode 속성을 "false"로 설정하면 문자열 매개 변수가 유니코드가 아닌 ASCII/MBCS 등의 형식으로 서버에 전송됩니다.

https://docs.microsoft.com/ko-kr/sql/connect/jdbc/setting-the-connection-properties?view=sql-server-ver15 

 

연결 속성 설정 - SQL Server

Microsoft JDBC Driver for SQL Server에 대한 연결 문자열 속성은 다양한 방식으로 지정할 수 있습니다.

docs.microsoft.com

        <property name="url" value="jdbc:log4jdbc:sqlserver://IP_Address:1433;databaseName=MSSQLDB_KOR;sendStringParametersAsUnicode=false" />
        <property name="username" value="sa" />
        <property name="password" value="1234" />
        <property name="defaultAutoCommit" value="false" />
        <property name="initialSize" value="10" />
        <property name="maxActive" value="200" />
        <property name="maxIdle" value="15" />
        <property name="minIdle" value="15" />
        <property name="maxWait" value="20000" />
        <property name="logAbandoned" value="true" />
        <property name="removeAbandoned" value="true" />
        <property name="removeAbandonedTimeout" value="60" />
        <property name="validationQuery" value="SELECT 1" />
        <property name="testOnBorrow" value="true" />
        <property name="testOnReturn" value="true" />

영문 Windows Server 에 SQL Server 를 설치하면 기본적으로 'SQL_Latin1_General_CP1_CI_AS' 로 설정됩니다.

이때 다국어(한글, 중국어 ..)을 사용하기 위해서는 NVARCHAR 를 사용해야 합니다.

그런데, 이게 여러가지 방법이 있습니다.

  Korean_Wansung_CI_AS SQL_Latin1_General_CP1_CI_AS 비고
VARCHAR 정상 입력/조회 가능 ?? 로 보여짐 한글 2Byte 나머지 잘림
NVARCHAR 정상 입력/조회 가능 정상 입력/조회 가능 설정된 Length 만큼 등록가능

※ 'Korean_Wansung_CI_AS' 에서 테스트된 한글 테스트

https://blog.danggun.net/1458

 

[MSSQL] varchar와 nvarchar 차이

당연한 이야기지만 varchar는 가변 문자열 nvarchar을 가변 유니코드 문자열 입니다. 다국어지원을 할거면 당연이 nvarchar를 사용하여야 합니다. (nchar, ntext 등등) 두가지를 나누는 이유는 varchar는 영

blog.danggun.net


System.Data.SqlClient.SqlException: equal to 작업에서의 "Korean_Wansung_CI_AS"과(와) "SQL_Latin1_General_CP1_CI_AS" 간의 데이터 정렬 충돌을 해결할 수 없습니다.


/* SQL Server의 COLLATION 확인 */
select serverproperty('collation')

/* Database 의 COLLATION 확인 */
SELECT name, collation_name FROM sys.databases;

/* COLLATION 종류 확인 */
SELECT * FROM ::fn_helpcollations()
/* 해당 DB에 테이블 전체 collation(인코딩) 조회 */
SELECT t.name TableName, c.name ColumnName, collation_name 
FROM sys.columns c 
inner join sys.tables t 
on c.object_id = t.object_id

/* 테이블의 COLLATION 조회 및 컬럼 속성 확인 */
SELECT COLUMN_NAME, CHARACTER_SET_NAME, COLLATION_NAME, DATA_TYPE, CHARACTER_MAXIMUM_LENGTH 
FROM INFORMATION_SCHEMA.COLUMNS 

https://docs.microsoft.com/ko-kr/sql/relational-databases/databases/rebuild-system-databases?view=sql-server-ver15 

 

시스템 데이터베이스 다시 빌드 - SQL Server

시스템 데이터베이스 다시 작성

docs.microsoft.com

https://axmvp.tistory.com/78

 

MS SQL Server 2008 R2에서 Collation 변경하기

setup.exe /QUIET /ACTION=REBUILDDATABASE /INSTANCENAME=instance_name /SQLSYSADMINACCOUNTS= accounts [/SAPWD=password] [/SQLCOLLATION=collation_name] setup /ACTION=REBUILDDATABASE /QUIET /INSTANCENAM..

axmvp.tistory.com

 

728x90

'Database' 카테고리의 다른 글

AWS 의 Database 설정 - Postgresql  (0) 2023.03.04
[H2] H2 DB 설치  (0) 2021.11.24
[MSSQL] 프로시저 생성 / 실행  (0) 2021.03.23
[Database] INNER JOIN , OUTER JOIN  (0) 2021.03.22
[MSSQL] TYPE, 배열의 사용  (0) 2021.02.10