지정된 로케일과 함께 sqlite3에서 텍스트를 정렬하는 방법은 무엇입니까?
-
03-07-2019 - |
문제
기본적으로 sqlite3는 ASCII 문자로만 정렬됩니다. Google을 보려고 노력했지만 내가 찾은 유일한 것은 콜라이트에 대한 정보였습니다. SQLITE3 만 있습니다 NOCASE
, RTRIM
그리고 BIARY
콜라이트. 특정 로케일에 대한 지원을 추가하는 방법? (Rails 응용 프로그램에서 사용하고 있습니다)
다른 팁
Doug Currie 답변을 받아 들였지만 SQLITE3 문서가 매우 이상하기 때문에 "알고리즘"을 추가하고 싶습니다.
좋아, 우리는 SQLITE3를 작동 시켰고 지금 :
컴파일 :
gcc -shared icu.c `icu-config --ldflags` -o libSqliteIcu.so
Linux입니다. 또한 추가 ICU 개발 패키지를 설치해야했습니다.
sudo apt-get install libicu-dev
64 비트 아키텍처를 작업하고 있으며 오류가 발생합니다.
__relocation R_X86_64_32S__
(무엇을 의미하든 :). GCC는 추가를 제안했습니다-fPIC
옵션을 컴파일하고 도움이되었습니다.sqlite3을 실행하십시오. 명령으로 확장을로드 할 수 있습니다.
.load './libSqliteIcu.so'
현재 디렉토리에 있다고 가정하면 전체 경로를 지정할 수도 있습니다.
새로운 Collation 만들기 :
SELECT icu_load_collation('pl_PL', 'POLISH');
첫 번째 매개 변수는 원하는 로케일이고 두 번째 매개 변수는 (무엇이든 할 수 있음)입니다.
이제 우리는 새로운 로케일과 데이터를 정렬 할 수 있습니다.
SELECT * FROM some_table ORDER BY name COLLATE POLISH;
그리고 그것은 둔감합니다!
ICU 확장을 컴파일 할 여유가 없다면 UDF가 동일하게 수행 할 수 있습니다. PHP/PDO에서 :
$pdo->sqliteCreateFunction('locale',
function ($data, $locale = 'root')
{
static $collators = array();
if (isset($collators[$locale]) !== true)
{
$collators[$locale] = new \Collator($locale);
}
return $collators[$locale]->getSortKey($data);
}
);
예제 사용 :
SELECT * FROM "table" ORDER BY locale("column", 'pt_PT');
나는이 접근법이 기본 확장만큼 효율적일 것으로 기대하지는 않지만 반드시 휴대가 가능합니다.
확장자를 스스로 구축 할 수없는 사람들을 위해 MacOS 및 Linux에서 컴파일 버전을 사용할 수있었습니다. http://files.tempel.org/various/sqlite3icuextention
Intel 32와 64 비트의 Linux 버전은 Ubuntu 16에 구축되었습니다.
일반적으로, 당신은 다른 사람들이 제공하는 컴파일 된 코드를 신뢰해서는 안되지만, 나는 상당히 공개적인 사람입니다. 즉, "나쁜"버전을 제공하면 상당히 위험을 감수 할 것입니다. 그리고 내 서버에 대한 중간의 공격 또는 해킹이 없는지 확인하려면 다음은 3 개의 파일에 대한 MD5 해시입니다.
libSqliteIcu-i386.so = 6decd73f27d9c61243128e798304508f
libSqliteIcu-x86_64.so = b127c8a1f65503c91c61a21732eb11be
sqlite3_icu_extension.dylib = a29d59f6b74e7ef234691729b82da660