2011-03-04 3 views
5

MySQL을 사용하여, 나는 정렬하고자하는 스페인어로 노래 목록을 선택합니다. 다음은 쿼리에서 반환 한 이름 목록입니다.mysql 또는 php에서 utf 문자를 사용하여 정렬 하시겠습니까? 최상의 솔루션

  • ¡ Decirevilla!
  • 알람 브라
  • 123 pasitos
  • 아프리카
  • 아 로즈
  • Decir

정렬 된 목록은 다음과 같아야합니다

  • 123 pasitos
  • 아프리카
  • 알함브라
  • Arroz
  • ¡ Decirevilla!
  • Decir
  • 내가 읽은 모든 연구 후

, 난이 사용하는 MySQL의를 달성하기 위해 합리적인 방법이 없다는 결론을 내렸다했습니다. 나는 콜레 션, 문자 세트 등을 시도했다. 그러나 원하는 결과에 따라 정렬 할 수있는 방법이 없다. Á도 내가 원하는 방식으로 정렬되어 있지 않습니다 ...

질문 1 : 이것은 합리적인 결론입니까?

나는 이것을 달성하는 유일한 방법은 PHP의 배열에 결과를 전달한 다음 사용자 정의 함수를 사용하여 배열을 정렬하는 것입니다 ...이 모든 함수는 usort를 사용하여 (값으로 정렬해야하고 ' 핵심 연합 유지에 관심 있음). 다음과 유사한 내용 :

function normalize($a, $b) { 
    if ($a == $b) { 
    return 0; 
    } 

    return ($a < $b) ? -1 : 1; 
} 


$tracks = array(); 

while ($row = $result->fetch_assoc()) { 
    $tracks[] = $row; 
} 

usort($tracks, 'normalize'); 

질문 2 : 맞춤 정렬을 수행하는 가장 좋은 방법입니까?

질문 3 : 여기

내가 벽을 치는거야 어디 내가 어떻게 내 요구에 따라 이름을 정렬하는 정규화 함수를 만드는 방법 아무 생각이 없습니다. 어떻게하면 특정 문자 (¡,?, ',!, ¿)를 무시할 수 있으며 다른 문자를 자연어로 대체 할 수 있습니까? (A -> A, E -> E 등) 나는 문자를 대체하고 다른 사람을 대체, 나는 정렬을 달성 할 수 있습니다. 나는 ...에 대한 것입니다.

질문 4 :이 모든 것이 의미가 있습니까? 나는 올바른 길을 가고 있는가?

미리 감사드립니다. Marco

답변

1

add your own collation을 MySQL에 연결할 수 있습니다. 그렇다면 당신이 관심을 두지 않는 문자를 무시하고 필요에 따라 악센트를 제거하고 원하는 일관된 방식으로 물건을 분류 할 수 있습니다.

데이터베이스에서 수행하는 것보다 클라이언트 측 (즉, 데이터베이스가 아닌 PHP로)에서 변경된 데이터 정렬을 수행하는 것이 빠릅니다. 쿼리에 LIMITOFFSET 절을 추가해야하는 즉시이 방법을 사용할 수도 있습니다. 사용자 지정 데이터 정렬이 MAX() 비슷한 기능을 수행하는지는 확실하지 않지만 전체 테이블을 가져 와서 정렬 한 다음 단 한 항목 만 가져 오지 않으려면 PHP에서 mangled-collation을 수행해야합니다.

그래서 최후의 수단으로 데이터베이스 외부에서 데이터 정렬을 수행하는 것이 좋습니다.

또 다른 옵션은 자신의 데이터 정렬을 작성하지 않으려는 경우 테이블에서 테이블을 올바르게 정렬하는 인공 열을 작성하는 것입니다. PHP 땅에서 normalize() 함수를 사용할 수 있습니다 (Jacob 's와 같은 것이 합리적인 출발점이 될 수 있습니다). 데이터베이스에 결과를 sortable_title이라는 열로 유지하십시오. ORDER BY sortable_title이 트릭을합니다.

  • 123 pasitos
  • 아프리카
  • 브라
  • 아 로즈 :이 같은 목록 (구두점, 모두 소문자, 악센트가 박탈 ...)를 생산 normalize() PHP 함수를 싶어
  • decirevilla
  • decir AS

그래서 간단한 CII- 베타컬 정렬은 옳은 일을 할 것입니다. 물론, INSERT를 수행 할 때 sortable_title을 초기화하고 UPDATE 중에 다시 생성해야하지만, 코드가 적절하게 캡슐화 된 경우에는 매우 간단합니다.

질문 4 : 저는 Jacob과 동의하지 않을 것이고 데이터베이스에서 데이터 정렬을 이동하여 올바른 방향으로 나아 가지 않을 것이라고 말합니다. 나는 당신이 완전히 길을 걷지는 않는다고 말하는 것이 아니라, 위에서 설명한 sortable_title 해킹과 같은 도움을 줄 수있을지라도 MySQL이 정렬을 처리하도록하는 것이 더 낫다.

+0

공유 호스트에있는 경우 MySQL에 자체 정렬을 추가 할 수 있습니까? – Marco

+0

@Marco : 호스팅 제공 업체에 따라 다르지만 아마도 "아마 그렇지 않을 것"쪽으로 기울어 질 것입니다. 그렇게 할 수 없다면'sortable_title' 방식으로 작업을 거의 완료 할 수 있습니다. –

+1

방금 ​​두 가지 방법 모두 프로그래밍을 마쳤으며 sortable_title을 사용하는 방법은 훨씬 빠릅니다. 타이머와 평균 결과를 mysql 솔루션에 추가했습니다 : 0.009 초 ... PHP 솔루션 : 0.12 초. 이상한 것은 ob_start() .. 메서드를 사용하여 목록을 캐싱했기 때문에 캐시가 눈에 띄게 느리다는 것입니다 ...이 특별한 경우에는 캐시 된 파일을 여는 것이 더 느려서 쿼리를 실행하는 것 같습니다. ..PHP에서 캐싱이 항상 필요한 것은 아닌지 궁금합니다 ... – Marco

0

질문 2. 맞춤 정렬을 수행하는 좋은 방법입니다. 그렇다면 비교 기능을 사용해야합니다.

질문 3 문자열을 iconv을 사용하여 ASCII 등가로 변환 할 가치가 있습니다. UTF-8을 ASCII로 변환 할 수 있으며 번역을 사용하면 그와 비슷한 모양으로 직접 변환 할 수없는 문자와 일치합니다.

즉Â -> A, É -> E 등.

일단 변환되면 preg_replace 또는 str_replace를 사용하여 정렬하지 않으려는 문자를 제거 할 수 있습니다.

다음은 사용할 수있는 비교 함수의 예입니다.

function normalize_string($string) { 
    $ascii = iconv("utf-8","ascii//TRANSLIT", $string); 
    return str_replace(array('!', "'", '?'), '', $ascii); 

    // or 

    return preg_replace('/[!\'?]/', '', $ascii); 

    // or depending on how much you do want to replace... \W => any "non-word" character 

    return preg_replace('/\W/', '', $ascii); 
} 

function custom_str_cmp($a, $b) { 
    return strcmp(normalize_string($a), normalize_string($b)); 
} 

usort($tracks, 'custom_str_cmp'); 

질문 4. 예.

관련 문제