데이터베이스 구성에서 Latin-1을 UTF-8보다 사용해야합니까?


65

우리는 내가 일하는 회사에서 MySQL을 사용하고 있으며 Ruby on Rails를 사용하여 클라이언트와 내부 애플리케이션을 모두 구축합니다.

여기서 일을 시작했을 때, 나는 전에는 결코 겪어 보지 못한 문제에 부딪쳤다. 프로덕션 서버의 데이터베이스는 Latin-1로 설정됩니다. 즉, 사용자가 UTF-8 문자를 복사하여 붙여 넣는 사용자 입력이있을 때마다 MySQL gem에서 예외가 발생합니다.

상사는이 "나쁜 캐릭터"라고 부릅니다. 대부분은 인쇄 할 수없는 캐릭터이기 때문에 제거해야한다고 말합니다. 이 작업을 수행하는 몇 가지 방법을 찾았지만 결국 UTF-8 문자가 필요한 상황이 발생했습니다. 또한이 문제에 대해 읽은 유일한 솔루션 인 것처럼 데이터베이스를 UTF-8로 설정하는 것만으로도 번거 로움이 있습니다.

Latin-1을 고수한다고 들었던 유일한 주장은 인쇄 할 수없는 UTF-8 문자를 허용하면 MySQL에서 텍스트 / 전체 텍스트 검색을 망칠 수 있다는 것입니다. 이것이 사실입니까?

UTF-8보다 Latin-1을 사용해야하는 다른 이유가 있습니까? 그것이 우수하고 유비쿼터스 화되고 있다는 것을 이해하고 있습니다.


4
@jon LATIN-1은 영어에 국한 되지 않습니다 . 내가 실수하지 않으면 스페인어뿐만 아니라 프랑스어도 완벽하게 포함되어 있습니다.
Darkhogg

4
@Darkhog : Latin1은 실제로 영어에만 국한되지는 않지만 본질적으로 서유럽 어 알파벳으로 제한됩니다.
Bart van Ingen Schenau

16
최신 시스템에서 UTF-8 대신 Latin 1을 사용하면 얻을 수있는 유일한 이점은 방해 행위입니다. 물론 이는 시스템의 소유자 나 개발자가 아닌, 방해 행위자 및 그들의 충성도가 누구에게나 도움이됩니다.
Jon Hanna

13
데이터베이스가 유로 기호 또는 내 이름 (דותן)을 보유 할 수 없을 정도로 나쁩니다.
dotancohen

20
비 라틴 -1 문자를 사용자 "복사하여 붙여 넣기"? 유니 코드를 장난 꾸러기 만 신경 쓰지 않는 관련없는 경건한 것으로 취급하지 마십시오. 우리의 꽤 많은 입력 정기적으로 라틴어-1에 맞지 않는 문자를 - 난 ♥, 많은 사람들이 비 유럽 언어를 듣고
Eevee

답변:


131

유니 코드는 확실히 어렵고 UTF-8 인코딩에는 몇 가지 불편한 속성이 있습니다. 그러나 UTF-8은 웹에서 사실상의 표준 인코딩이되어 ASCII, Latin-1, UCS-2 및 UTF-16을 능가합니다. 그냥 모든 곳에서 UTF-8을 사용 .

유니 코드를 지원해야하는 가장 중요한 이유는 사용자 입력에 대해 불필요한 가정을하지 않아야하기 때문입니다. 도메인이 무엇인지 잘 모르겠지만 히브리어 사용자 이름, 중국에 대한 블로그 게시물, Emoji에 대한 주석 또는 "this"와 같이 간단하게 스타일이 지정된 텍스트가 가능해야합니다. “”)가 아닌 ""괄호 및 줄임표 (영문)는 영어에서 일반적이지만 ASCII 또는 Latin-1에서는 지원되지 않는 문자입니다. 따라서 다른 스크립트를 지원하지 않는 것은 다른 문화에 큰 영향을 미치지 않을뿐만 아니라 Latin-1을 고수한다고해서 올바른 영어를 쓰지 못할 수도 있습니다.

유니 코드에 "잘못된 문자"만 허용한다는 개념은 잘못되었습니다. 예, 텍스트는 정말 복잡하며 유니 코드는 텍스트를 숨기지 않습니다. 상사는 구성 문자에 대해 생각할 수 있습니다. a예를 들어 , 하나의 기본 코드 포인트는 예를 들어 분음 부호를 나타내는 후속 분음 부호에 의해 수정되어와 같은 하나의 시각적 문자를 형성 á합니다. 어떤 종류의 정규화를 수행하면 검색을 시도 할 때 실제로 방해가되지 않습니다. 예를 들어, 모든 텍스트를 NFC 형식으로 저장할 수 있으며 이러한 텍스트는 사용 가능한 경우 사전 구성된 형식으로 축소합니다. 검색 할 때 텍스트에서 모든 작성 문자를 제거 할 수도 있지만 일부 언어에서는 의미가 크게 변경 될 수 있습니다.

유니 코드는 또한 인쇄 할 수없는 많은 문자를 추가하지만 ASCII조차도 많은 문자를 가지고 있습니다. 줄 중간에 NUL을 처리 하시겠습니까? “파일 분리기”인 0x1C는 어떻습니까? 나는 그 절반을 본 적이 없다 . Latin-1은 단어 분리 기회를 나타내는 부드러운 하이픈을 추가하지만 그렇지 않으면 보이지 않습니다. 이로 인해 전체 텍스트 검색이 중단됩니까? 다시 말해, ASCII 및 Latin-1조차도 입력 가능한 텍스트라고 가정하면 입력을 완전히 끊을 수 있습니다!


8
데이터베이스 관점에서, 이러한 문자 중 일부는 텍스트 유형 필드 (text / varchar / char / etc.)에서 허용되지 않아야합니다. MySQL 이러한 데이터 유형에서 널 문자를 허용하지만 PostgreSQL과 같은 다른 데이터베이스 허용하지 않습니다. 이러한 문자를 저장하려면 BLOB (MySQL) 또는 BYTEA (PostgreSQL)를 사용해야합니다.
cimmanon

15
"Latin-1을 고수해도 올바른 영어를 쓸 수 없습니다."좋은 점입니다. 그렇지 않으면 유니 코드가 더 강해집니다. ;-)
중복 제거기

3
@ PaŭloEbermann Embedded NUL 문자는 데이터가 문자열이 아니라 이진 얼룩임을 의미합니다. UTF-8 \0이 다중 바이트 인코딩의 일부로 바이트를 사용하여 UTF-8을 인식하지 않는 코드가 문자열 중간에서 멈추지 않도록하기 때문에 NUL은 이상한 예였습니다 .
Peter Cordes

7
모든 유니 코드 문자를 인쇄 할 수 있습니다. 올바른 글꼴이 필요합니다 :-)
James Anderson

4
@JamesAnderson 그런 다음 글꼴이 잘못되고 손상되었습니다. en.wikipedia.org/wiki/Unicode_control_characters
djechlin

62

기술적 인 문제를 넘어 서면, 당신의 상사는 현재 표준을 최신 상태로 유지할 시간이 없을 것입니다.

그의 입장은 완전히 점심을 먹지 않았고, 구식이 되었으므로이 문제를 논의 할 때 자신의 입장을 존중하고 ( 논쟁하지 말고 토론 해야 함을 기억해야 함 ) UTF-8과 관련하여 그가 우려하는 것을 통해 노력하십시오. 근본적인 문제는 기술적 인 문제가 아니며 일부 소프트 스킬 협상이 필요할 수 있습니다.


6
더 승인 할 수 없습니다. 사실 나는 내 자신의 대답으로이 문제에서 가장 중요한 "인간 측면"을 완전히 간과 한 것을 후회한다. 한 번 이상
공표

2
외부 라틴어-1의 모든 호출 bad character이는 생각은 non-printable이다 just out-dated당신에게?
njzk2

2
실제 문제는 "우리가 다루고있는 기술적 문제입니까?"입니다. 나는 OP의 상사가 학교에 가서 이것을 배웠거나 기술 매뉴얼 / 저널을 읽고 그 결론에 도달했다고 생각하지 않습니다. 솔루션이 엄밀히 기술적 인 솔루션이라는 것을 이해하지 못합니다. 아이러니하게도이 의견은이 문제의 핵심을 정확하게 보여줍니다. 잘못 처리하면이 문제를 해결하는 것이 매우 불쾌 할 수 있습니다.
Nelson

49

우리 중 어느 것이 옳습니까?

옛날 옛적에, 당신의 상사는 있었다. 그러나 시간이 지남에 따라 상황이 바뀝니다. 요즘, 당신은 (하지만 상사에게 달려 가기 전에 넬슨의 답변도 읽어보십시오 ).

이전 버전의 MySQL과 대부분의 모든 버전은 UTF8보다 이전 Latin1 / ISO-8859-1 (5)를 훨씬 잘 처리했습니다.

UTF8이 주로 어디에서나 생성, 진화 및 푸시 된 이유가 있습니다. 제대로 구현되면 훨씬 더 잘 작동합니다 . Latin1 문자가 8 비트 인 반면 UTF8 문자는 8-32 비트 일 수 있다는 사실에서 비롯된 일부 성능 및 스토리지 문제가 있습니다. 따라서 계획 VARCHAR할 때이 점을 고려해야합니다. 그리고 검색 루틴이 조금 느려질 것입니다. 학생들 더 많은 일을 할 수 있지만 (예 : 악센트 구분이 있거나없는 검색 . 광범위한 작업없이 Latin1에서는 검색 할 수 없음) 시간이 좀 더 걸립니다.

그러나 반면에 스토리지는 저렴 하고 파일 크기에 대한 현실적인 오버 헤드는 2-3 % 미만이며 컴퓨팅 성능도 저렴하며 Moore의 법칙에 따라 저렴 해집니다. 동안 당신의 시간고객의 기대는 확실히 아니다 .

그러한 도구 를 개발 하는 사람이라면 검색 도구 등을 걱정해야 할 수도 있습니다 . 그러나 당신은 아마 아닐 것입니다. 당신이 사용 하는 도구; 어제 UTF8과 완벽하게 호환되지 않는 것 (이전 MySQL은 그렇지 않았 음)도 오늘이거나 곧있을 것입니다 (예 : utf8mb4를 지원하는 MySQL).

그래서 조심스럽게 (계획 및 UTF8 올바른 방법을 구현 하지 당신은 매우 합리적입니다 코드를 가질 수 군더더기로 라틴어 그것을 통해 두드림) 미래 지향적 , 혹시 어떤 아시아 국가와 사업을 할 계획이라면, 아주 좋은 것입니다 의회. 그리고 그러한 계획이 없다면 다른 사람들이 가질 것이며, 그 사람들은 고객, 공급 업체 또는 파트너가 될 수 있습니다.

따라서 UTF8 데이터를 보내기 시작하면 Latin1로 변환하거나 변환 할 수없는 복잡한 것을 설정하고 해결할 수없는 경우를 처리해야합니다.

예산을 고려 하여 사악한 모모 베이크 닌자 에 대한 몇 가지 분쟁의 비용을 고려하고 이미 발견 한 것처럼 사라지지 않을 것이라고 생각하면 UTF8로가는 것이 더 간단 할뿐만 아니라 실현 될 것입니다. 더 저렴 합니다.


4

ASCII로만 문자 세트를 제한하는 것이 의미가있는 일부 상황은 제한이있는 선택 필드 (예 : 상태 필드)가있을 수 있습니다. 여기에는 가능한 값을 엄격하게 제어하기 때문에 외부 시스템에 대한 외래 키 / 참조가 있습니다. 영숫자 문자와 몇 가지 기호 만 있으면됩니다.

다른 텍스트의 경우 UTF-8 만 사용하십시오.


2
MySQL에는 열거 형이 없습니까?
raptortech9797

2
ASCII는 UTF8의 하위 집합이므로 UTF8 만 사용하십시오.
RemcoGerlich

@ RemcoGerlich : UTF8을 사용할 수 있다는 데 동의하지 않습니다. 내 관점에서 외부 참조는 텍스트가 아니라 불투명 한 바이트 시퀀스입니다. 표기법의 편의를 제외하고는 문자셋이 없습니다. 바이트 시퀀스가 ​​특정 문자 집합으로 해석되는 경우 데이터베이스가 아닌 외부 시스템 또는 응용 프로그램 도메인입니다.
Lie Ryan

3
@LieRyan : 그 시점을 알지만 ASCII가 아니어야합니다. 아마도 이진 blob 형식 일 수도 있습니다.
RemcoGerlich

3

답을 시작하기 위해서는 서버 구성 방법이 중요하지 않습니다 . MySQL에서 문자 인코딩은 열별로 구성 할 수 있습니다 (즉, 동일한 테이블이 여러 인코딩으로 문자를 보유 할 수 있음을 의미 함). 즉, 내 서버 (및 서버의 여러 레거시 데이터베이스)는 연결시 올바른 데이터 정렬을 설정할 수없는 이전 클라이언트 (다른 ​​하드웨어 클라이언트)에 대해 기본적으로 cp1251로 구성되지만 프로덕션의 기본 데이터베이스는 모두 UTF-8을 사용합니다.

"공간 낭비"라고 말하면 실제로 중요한 데이터를 낭비라고 할 수는 없습니까? 그러나 저장 공간 증가는 데이터가 사용되는 언어에 따라 달라집니다. 사이트가 주로 영어 인 경우 중요하지 않은 (1 % 미만) 증가하고 ASCII 범위를 벗어난 문자를 사용하여 우편물 인 경우 최대 100 % . 그리고 더 동쪽으로 가면 이후의 UTF-8 (소위 UTF8mb4) 사양은 코드 포인트 당 최대 4 바이트를 허용합니다.

그리고 "올바른 사람"에게… 진실은 기술적 인 것 이상의 사회적 질문입니다. 특정 서버 설정에 대한 유효한 이유가있을 수 있지만 그 의미를 알아야합니다. 그러나 나에게 묻는다면 UTF-8을 사용하지 않을 이유가 없습니다. 그것은 세상의 모든 텍스트를 지배하는 유일한 종류입니다.


MySQL은 데이터를 열 인코딩으로 변환하기 전에 데이터베이스 인코딩으로 데이터를 변환하려고 시도합니다. utf8 클라이언트, latin1 데이터베이스 및 utf8 columnt가 있으면 텍스트 데이터가 손실 될 수 있습니다.
Ivan Solntsev

이반, 그것은 완전히 다른 질문입니다. 문자 집합 클라이언트, 문자 집합 서버, 문자 집합 연결, 문자 집합 결과 간의 상호 작용은 MySQL 문서에서 긴 기사입니다. 열별 데이터 정렬 설정의 경우 "데이터베이스 데이터 정렬"은 열 데이터 정렬이며 데이터베이스 데이터 정렬을 무시하고 문자 집합 결과로 직접 변환됩니다.
AnrDaemon

0

UTF-8이 웹 트래픽의 기본값이라고 설명하십시오. 또한 모든 사용자는 브라우저에 유효한 유니 코드 문자를 입력 할 수 있습니다.

utf-8-> latin-1-> utf-8에서 발생하는 많은 다양한 문제를 처리하는 것보다 프론트 엔드에서 백 엔드까지 utf-8 / unicode를 사용하는 것이 훨씬 쉽습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.