2014-01-06 7 views
4

많은 사람들이 알고 있다고 확신하기 때문에 독일 움라우트 및 UTF8 데이터 정렬을 처리하는 것은 문제가 될 수 있습니다. a = ä, o = ö, u = ü과 같은 항목은 결과의 정렬 순서뿐만 아니라 실제 결과에도 영향을 미칠 수 있습니다. 다음은 명사의 단수형과 복수형을 구별하기 만하면 잘못 될 수 있음을 명확하게 보여주는 예입니다 (Bademantel - 단수, Bademäntel - 복수형).독일어 움라우트 및 UTF8 데이터 정렬

CREATE TABLE keywords (
    id INT (11) PRIMARY KEY AUTO_INCREMENT, 
    keyword VARCHAR (255) NOT NULL 
) ENGINE = MyISAM DEFAULT CHARACTER 
SET = utf8 COLLATE = utf8_unicode_ci; 

INSERT INTO keywords (keyword) VALUES ('Bademantel'), ('Bademäntel'); 

SELECT * FROM keywords WHERE keyword LIKE ('%Bademäntel%'); 

결과

+----+------------+ 
| id | keyword | 
+----+------------+ 
| 1 | Bademäntel | 
+----+------------+ 

아직 utf8_unicode_ci으로 출력이 분명히 필요없는 결과

+----+------------+ 
| id | keyword | 
+----+------------+ 
| 1 | Bademantel | 
| 2 | Bademäntel | 
+----+------------+ 

이다이어야한다.

실제 문제는 현재 프로젝트에서 발생합니다. 기본적으로 웹 사이트의 모든 키워드를 해당 제품 페이지에 대한 링크로 대체해야하는 키워드 파서를 작성하는 것입니다. 자원의 불필요한 낭비를 방지하기 위해 별개의 키워드 중 하나

SELECT keyword FROM keywords GROUP BY keyword ORDER BY LENGTH(keyword) DESC 

또는

SELECT DISTINCT keyword FROM keywords ORDER BY LENGTH(keyword) DESC 

프로세스 (링크)에 모든 단어가 아닌 움라우트 버전의 실패가 발생합니다 인출 만 사용하여 단순히 (즉, Bademäntel을 포함하는 모든 키워드는 반입되지만 Bademantel은 생략됩니다).

이제이 문제를 해결할 수있는 몇 가지 옵션이 있다는 것을 알고 있습니다.

1) 키워드 테이블 또는 쿼리 중에 기존 코드를 많이 수정하지 않아도되는 utf8_swedish_ci을 사용하십시오. 불행하게도

SELECT DISTINCT keyword COLLATE utf8_swedish_ci AS keyword FROM keywords ORDER BY LENGTH(keyword) DESC; 

내가 (ssß)이 같은 고려는 "Eszett"를 정렬 정말 좋은 기능을 제공)이 있기 때문에 utf8_unicode_ci을 포기하는 것을 꺼려하지 않다, b)는 어떻게 든 그것은 단순히를 사용하는 잘못된 느낌 독일어 관련 자료를 처리하기위한 스웨덴어 조합

2) utf8_bin을 사용하도록 기존 코드를 수정하십시오.

SELECT DISTINCT keyword COLLATE utf8_bin AS keyword FROM keywords ORDER BY LENGTH(keyword) DESC; 

이 작동 것이 아니라이 모든 비교가 나는 문제에 대한 해결책으로 utf8_bin에 의존하기로 결심했다면 나는 대소 문자를 구분하고 힘든 시간을 것이라는 점을 의미 대소 문자를 구분 심한 단점이있다으로 LIKE('%Mäntel%')과 같은 검색어는 Bademäntel과 같은 레코드를 가장 명확하게 생략합니다.

나는이 질문이 지금도 계속 튀어 나와 있지만 일부 답변은 꽤 오래된 것으로 알고 있으며 그 동안에는 다른 해결책이 있는지 알고 싶습니다. 나는 간단한 질의가 질의 결과를 완전히 바꿀 수 있다고 생각할 수는 없다. 정렬 순서 예, 결과 자체?

조금 더 긴 게시물과 모든 종류의 조언이나 의견에 미리 감사드립니다.

+0

[* MySQL Charset/Collate *] (http://mysql.rjweb.org/doc.php/charcoll) –

답변

1

이 문제가 발생하면 since MySQL 5.6에 위의 모든 문제를 해결하는 utf8_german2_ci 데이터 정렬에 대한 공식적인 지원이 있다는 점에 유의할 가치가 있습니다. 늦어서는 안되는 것보다.

0

키워드 WHERE BINARY keyword = 'Bademantel'을 사용하여 이진 검사를 사용할 수 있습니다. 결과는 예상 된 결과입니다. 이 보여이 sqlfiddle 밖으로

확인 :

이 여기에 행동에 대해
SELECT * FROM stackoverflow WHERE BINARY keyword = 'Bademantel'; 

| id | keyword | 
|----|------------| 
| 1 | Bademantel | 

SELECT * FROM stackoverflow WHERE keyword = 'Bademantel'; 

| id | keyword | 
|----|------------| 
| 1 | Bademantel | 
| 2 | Bademäntel | 

더 : 여기 What effects does using a binary collation have?하고 있습니다 : 독일어 움라우트 또는 프랑스어 무덤 악센트 또는 체코 특수 문자와 애플리케이션에 따라서 What is the best MySQL collation for German language

을/polish 언어는 응용 프로그램에 가장 적합한 행동을 결정해야합니다.

대부분의 경우는 utf8_general_ci 일 수 있지만 가끔 Bademantel과 같은 경우에는 utf8_bin을 사용해야합니다.

문자열 비교가 전혀 나쁘지 않습니다. utf8_general_ci 가끔 도움이 될 것입니다. Straße과 같은 문자열을 저장하고 을 반환하는 Strasse을 검색 할 수 있습니다.

+0

제안 해 주셔서 감사합니다. 그러나 이미 원본에서 설명한 내용에 대해 명확한 이진 비교가 있으며, 가장 중요한 것은 대/소문자 구분입니다. MySQL 5.6에서 소개 된'utf8_german2_ci'는이 문제에 대한 최종 해결책입니다. – brezanac

+0

예를 들어, MySQL 5.5가있는 프로덕션 서버에 고정되어있는 경우를 제외하고는 – CodeBrauer

관련 문제