SQL Server 데이터베이스에서 UTF-8 데이터 정렬을 사용하는 방법은 무엇입니까?


84

UTF8을 사용하여 mysql에서 SQL Server (정치), 원래 mysql 데이터베이스로 데이터베이스를 마이그레이션했습니다.

이제 SQL Server 2008이 utf8을 지원하지 않는다는 /dba/7346/sql-server-2005-2008-utf-8-collation-charset 을 읽었습니다 . 농담입니까?

SQL Server는 대부분 라틴어로 인코딩 된 여러 데이터베이스를 호스팅합니다. 마이그레이션 된 db는 웹 게시 용이므로 utf8 인코딩을 유지하고 싶습니다. 놓친 것이 있거나 응용 프로그램 수준에서 enc / dec이 필요합니까?


실제로 SQLCLR UDF를 생성하여 UTF8 사용에 문제가 없으며 Microsoft에서 코드를 다운로드 할 수 있습니다. 다음 링크를 확인 하십시오
Ronen Ariely 2015 년

1
Java, JavaScript, DotNet 및 Windows는 모두 내부적으로 UTF-16을 사용하므로 웹 사이트가 이들 중 하나로 코딩되면 UTF16으로 변환을 저장하게됩니다.
Ben

1
도움이된다면 SQL Server가 내부적으로 텍스트를 UTF-8로 저장한다고 가정 할 수 있습니다. 드라이버는이를 검색 할 때 다시 UTF-16으로 변환합니다. SQL Server가 텍스트를 UCS-32로 저장한다고 가정 할 수도 있습니다. 내부 저장소 형식은 관련없는 구현 세부 정보입니다. 중요한 것은 데이터베이스가 유니 코드 문자 데이터를 UTF-16 (프로그래밍 환경과 일치)으로 반환한다는 것입니다.
Ian Boyd

답변:


26

아니! 농담이 아닙니다.

여기를보십시오 : http://msdn.microsoft.com/en-us/library/ms186939.aspx

고정 길이, nchar 또는 가변 길이, nvarchar, 유니 코드 데이터이고 UNICODE UCS-2 문자 집합을 사용하는 문자 데이터 형식입니다.

또한 여기 : http://en.wikipedia.org/wiki/UTF-16

이전 UCS-2 (2 바이트 범용 문자 집합)는 1996 년 7 월 유니 코드 표준 버전 2.0에서 UTF-16으로 대체 된 유사한 문자 인코딩입니다.


확인. mssql-client가 외부 UTF8 세계로 변환 될 수 있습니까?
Teson 2014 년

mssql-client모든 것이 될 수 있습니다. Java, .NET, C, PHP 등 ... 클라이언트는 무엇을 의미합니까?
edze

1
클라이언트 : php에서 sqlsrv 확장. Robert는 여기에 일반 텍스트를 넣었 습니다. social.msdn.microsoft.com/Forums/en/sqldriverforphp/thread/… , 결과를 평가하고 게시합니다.
Teson

2
안녕하세요, 지연에 대해 죄송하지만 담당자에게 감사드립니다. 연결 문자열에서 sqlsrv_connect (, array ( "CharacterSet"=> "UTF-8") .. 사용하면 잘 작동합니다. PDO가 나왔습니다. 맞습니까?
Teson

33

UTF-8은 문자 집합이 아니라 인코딩입니다. UTF-8의 문자 집합은 유니 코드입니다. 유니 코드 텍스트를 저장하려면 nvarchar데이터 유형 을 사용합니다 .

데이터베이스가 UTF-8을 사용하여 텍스트를 저장하는 경우 텍스트를 인코딩 된 UTF-8 데이터로 가져 오지 않고 디코딩 된 텍스트로 가져옵니다.

UTF-8로 인코딩 된 텍스트를 데이터베이스에 쉽게 저장할 수 있지만 텍스트로 저장하지 않고 바이너리 데이터 ( varbinary) 로 저장합니다 .


입력 해 주셔서 감사합니다. 예를 들어 stackoverflow.com/questions/3951722/…를
Teson

나는 이것에 대해 내 머리를 가질 수 없습니다. "UTF8의 문자 집합은 유니 코드입니다"?? utf8은 유니 코드보다 넓지 않습니다. Dauðalogn을 unicode vs utf8로 저장하면 다른 결과가 나타납니다. (EF BB BF) 44 61 75 C3 B0 61 6C 6F 67 6E vs \ u0044 \ u0061 \ u0075 \ u00f0 \ u0061 \ u006c \ u006f \ u0067 \ u006e
Teson

2
@ user247245 : UTF-8은 인코딩이고 유니 코드는 문자 집합입니다. UTF-8은 유니 코드를 저장하는 한 가지 방법입니다. 유니 코드를 나타내는 데 사용한 것은 문자열 리터럴에 사용되는 이스케이프 코드이며 일반적으로 유니 코드를 파일로 나타내는 방법은 아닙니다. UTF-32는 Uncode에서 파일 형식으로 직접 가장 가까운 번역이며 각 문자 코드는 32 비트 숫자로 저장됩니다.
Guffa 2015 년

위의 예에서 세 번째 문자가 UTF8로 C3 B0으로 표시되고 유니 코드로 간단히 F0으로 표시되는 이유를 설명해 주시겠습니까? 당신의 도움을 주셔서 감사합니다.
Teson 2015-09-04

4
@ user247245 : 8 ~ 11 비트 사이의 문자 코드 110xxxxx 10xxxxxx는 UTF-8 ( x데이터 비트를 나타냄) 에서처럼 인코딩 되므로 문자 코드 F0( 0001111000011 비트)는 다음과 같이 인코딩됩니다 11000011 10110000( 00011문자 코드에서 첫 번째 바이트와 110000두 번째 바이트) )입니다 C3 B0.
Guffa 2015 년

24

이것이 SQL Server 2019에서 마침내 지원 될 것 같습니다! SQL Server 2019-새로운 기능

BOL에서 :

UTF-8 지원

가져 오기 또는 내보내기 인코딩으로 널리 사용되는 UTF-8 문자 인코딩 또는 텍스트 데이터에 대한 데이터베이스 수준 또는 열 수준 데이터 정렬을 완벽하게 지원합니다. UTF-8은 CHARVARCHAR데이터 유형 에서 허용되며 객체의 데이터 정렬을 UTF8접미사 가있는 데이터 정렬로 만들거나 변경할 때 활성화됩니다 .

예를 들어, LATIN1_GENERAL_100_CI_AS_SCLATIN1_GENERAL_100_CI_AS_SC_UTF8. UTF-8은 SQL Server 2012에 도입 된 보조 문자를 지원 NCHAR하고 NVARCHARUTF-16 인코딩 만 허용하며 변경되지 않은 상태로 유지 되는 Windows 데이터 정렬에만 사용할 수 있습니다 .

이 기능은 사용중인 문자 집합에 따라 상당한 저장 공간을 절약 할 수 있습니다. 예를 들어 ASCII 문자열이있는 기존 열 데이터 유형을 UTF-8 지원 데이터 정렬 NCHAR(10)CHAR(10)사용하는 것으로 변경하면 스토리지 요구 사항이 거의 50 % 감소합니다. 이 감소는 NCHAR(10)저장에 22 바이트가 CHAR(10)필요한 반면 동일한 유니 코드 문자열에는 12 바이트가 필요 하기 때문 입니다.

2019-05-14 업데이트 :

문서는 지금 업데이트 된 것으로 보이며 " 데이터 정렬 및 유니 코드 지원 섹션에서 MSSQL 2019의 옵션을 설명합니다. " .

2019-07-24 업데이트 :

Pedro Lopes의 기사 -Azure SQL Database에 대한 UTF-8 지원 소개에 대한 Microsoft의 선임 프로그램 관리자


4

마이크로 소프트 SQL 서버 2016로, UTF-8에 의해 지원됩니다 bcp, BULK_INSERT하고 OPENROWSET.

부록 2016-12-21 : SQL Server 2016 SP1은 이제 Standard 및 Express를 포함한 모든 버전의 MS SQL에 대해 유니 코드 압축 (및 이전의 대부분의 다른 엔터프라이즈 전용 기능)을 활성화합니다. 이것은 UTF-8 지원과 동일하지 않지만, 목표가 서양 알파벳의 디스크 공간 감소 인 경우 유사한 이점을 제공합니다.


하지만 OPENQUERY가 아닌가요? 이것이 OPENQUERY를 사용하여 Oracle에서 CLOB 데이터를 마이그레이션하는 데 문제가있는 이유인지 궁금합니다.
Geoff Dawdy 19

4

T-SQL에서 UTF-8을 처리하는 두 개의 UDF :

CREATE Function UcsToUtf8(@src nvarchar(MAX)) returns varchar(MAX) as
begin
    declare @res varchar(MAX)='', @pi char(8)='%[^'+char(0)+'-'+char(127)+']%', @i int, @j int
    select @i=patindex(@pi,@src collate Latin1_General_BIN)
    while @i>0
    begin
        select @j=unicode(substring(@src,@i,1))
        if @j<0x800     select @res=@res+left(@src,@i-1)+char((@j&1984)/64+192)+char((@j&63)+128)
        else            select @res=@res+left(@src,@i-1)+char((@j&61440)/4096+224)+char((@j&4032)/64+128)+char((@j&63)+128)
        select @src=substring(@src,@i+1,datalength(@src)-1), @i=patindex(@pi,@src collate Latin1_General_BIN)
    end
    select @res=@res+@src
    return @res
end

CREATE Function Utf8ToUcs(@src varchar(MAX)) returns nvarchar(MAX) as
begin
    declare @i int, @res nvarchar(MAX)=@src, @pi varchar(18)
    select @pi='%[à-ï][€-¿][€-¿]%',@i=patindex(@pi,@src collate Latin1_General_BIN)
    while @i>0 select @res=stuff(@res,@i,3,nchar(((ascii(substring(@src,@i,1))&31)*4096)+((ascii(substring(@src,@i+1,1))&63)*64)+(ascii(substring(@src,@i+2,1))&63))), @src=stuff(@src,@i,3,'.'), @i=patindex(@pi,@src collate Latin1_General_BIN)
    select @pi='%[Â-ß][€-¿]%',@i=patindex(@pi,@src collate Latin1_General_BIN)
    while @i>0 select @res=stuff(@res,@i,2,nchar(((ascii(substring(@src,@i,1))&31)*64)+(ascii(substring(@src,@i+1,1))&63))), @src=stuff(@src,@i,2,'.'),@i=patindex(@pi,@src collate Latin1_General_BIN)
    return @res
end
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.