Collations

Collations (정렬 규칙)

Collations는 실행 엔진에서 텍스트를 정렬하거나 비교하는 방법에 대한 규칙을 제공해요. 언어나 국가에 따라 텍스트 정렬 규칙이 다르기 때문에, 로컬라이제이션을 위해 Collations가 유용해요. 사용자는 정렬과 비교 연산을 수행할 때 사용할 collation을 선택해야 해요.

출처: 문서

본문

Collations는 실행 엔진에서 텍스트를 정렬하거나 비교하는 방법에 대한 규칙을 제공해요. Collations는 로컬라이제이션에 유용해요. 텍스트를 정렬하는 규칙은 언어나 국가에 따라 다르기 때문이에요. 이러한 정렬은 종종 서로 호환되지 않아요. 예를 들어 영어에서 문자 yxz 사이에 와요. 그러나 리투아니아어에서 문자 yij 사이에 와요. 그런 이유로 서로 다른 collations가 지원돼요. 정렬과 비교 연산을 수행할 때 사용자는 어떤 collation을 사용할지 선택해야 해요.

기본적으로 BINARY collation이 사용돼요. 즉, 문자열은 바이너리 내용만을 기준으로 정렬되고 비교돼요. 이는 표준 ASCII 문자(즉, A-Z와 숫자 0-9)에 대해 의미가 있지만, 특수 유니코드 문자에는 일반적으로 별로 의미가 없어요. 그렇지만 정렬과 비교를 수행하는 가장 빠른 방법이에요. 따라서 특별히 필요한 경우가 아니라면 BINARY collation을 유지하는 것이 권장돼요.

BINARY collation은 CPOSIX라는 별칭으로도 사용할 수 있어요.

경고 DuckDB의 Collation 지원에는 몇 가지 알려진 제한이 있고 여러 개선 계획이 있어요.

Collations 사용

DuckDB의 스탠드얼론 설치는 세 가지 collations를 포함해요: NOCASE, NOACCENT, NFC. NOCASE collation은 대소문자와 무관하게 문자를 동일하게 비교해요. NOACCENT collation은 악센트와 무관하게 문자를 동일하게 비교해요. NFC collation은 NFC-정규화 비교를 수행해요. 자세한 내용은 Unicode normalization을 참고해요.

SELECT 'hello' = 'hElLO';
false
SELECT 'hello' COLLATE NOCASE = 'hElLO';
true
SELECT 'hello' = 'hëllo';
false
SELECT 'hello' COLLATE NOACCENT = 'hëllo';
true

Collations는 점 연산자로 연결해 결합할 수 있어요. 다만 모든 collations가 함께 결합될 수 있는 것은 아니라는 점에 주의해요. 일반적으로 NOCASE collation은 다른 어떤 collator와도 결합될 수 있지만, 대부분의 다른 collations는 결합될 수 없어요.

SELECT 'hello' COLLATE NOCASE = 'hElLÖ';
false
SELECT 'hello' COLLATE NOACCENT = 'hElLÖ';
false
SELECT 'hello' COLLATE NOCASE.NOACCENT = 'hElLÖ';
true

기본 Collations

지금까지 본 collations는 모두 표현식별로 지정됐어요. 글로벌 데이터베이스 수준 또는 기본 테이블 컬럼에서 기본 collator를 지정하는 것도 가능해요. PRAGMA default_collation을 사용해 전역 기본 collator를 지정할 수 있어요. 이것은 다른 collator가 지정되지 않을 때 사용될 collator예요.

SET default_collation = NOCASE;
SELECT 'hello' = 'HeLlo';
true

Collations는 테이블을 만들 때 컬럼별로도 지정할 수 있어요. 해당 컬럼이 비교에서 사용되면 컬럼별 collation이 그 비교를 수행하는 데 사용돼요.

CREATE TABLE names (name VARCHAR COLLATE NOACCENT);
INSERT INTO names VALUES ('hännes');
SELECT name
FROM names
WHERE name = 'hannes';
hännes

다만 서로 다른 collations는 결합될 수 없으므로 주의해요. 이는 서로 다른 collation이 지정된 컬럼을 비교하려 할 때 문제가 될 수 있어요.

SELECT name
FROM names
WHERE name = 'hannes' COLLATE NOCASE;
ERROR: Cannot combine types with different collation!
CREATE TABLE other_names (name VARCHAR COLLATE NOCASE);
INSERT INTO other_names VALUES ('HÄNNES');
SELECT names.name AS name, other_names.name AS other_name
FROM names, other_names
WHERE names.name = other_names.name;
ERROR: Cannot combine types with different collation!

collation을 수동으로 덮어써야 해요.

SELECT names.name AS name, other_names.name AS other_name
FROM names, other_names
WHERE names.name COLLATE NOACCENT.NOCASE = other_names.name COLLATE NOACCENT.NOCASE;
name other_name
hännes HÄNNES

ICU Collations

지금까지 본 collations는 지역에 의존하지 않고 특정 지역 규칙을 따르지 않아요. 특정 지역이나 언어의 규칙을 따르려면 ICU collations 중 하나를 사용해야 해요. 그러려면 ICU 확장을 로드해야 해요.

이 확장을 로드하면 데이터베이스에 여러 언어 및 지역 특정 collations가 추가돼요. 이들은 PRAGMA collations 명령 또는 pragma_collations 함수를 쿼리해 확인할 수 있어요.

PRAGMA collations;
SELECT list(collname) FROM pragma_collations();
[af, am, ar, ar_sa, as, az, be, bg, bn, bo, br, bs, ca, ceb, chr, cs, cy, da, de, de_at, dsb, dz, ee, el, en, en_us, eo, es, et, fa, fa_af, ff, fi, fil, fo, fr, fr_ca, fy, ga, gl, gu, ha, haw, he, he_il, hi, hr, hsb, hu, hy, icu_noaccent, id, id_id, ig, is, it, ja, ka, kk, kl, km, kn, ko, kok, ku, ky, lb, lkt, ln, lo, lt, lv, mk, ml, mn, mr, ms, mt, my, nb, nb_no, ne, nfc, nl, nn, noaccent, nocase, om, or, pa, pa_in, pl, ps, pt, ro, ru, sa, se, si, sk, sl, smn, sq, sr, sr_ba, sr_me, sr_rs, sv, sw, ta, te, th, tk, to, tr, ug, uk, ur, uz, vi, wae, wo, xh, yi, yo, yue, yue_cn, zh, zh_cn, zh_hk, zh_mo, zh_sg, zh_tw, zu]

이 collations는 이전에 다른 collations가 사용된 것처럼 사용할 수 있어요. NOCASE collation과도 결합할 수 있어요. 예를 들어 독일어 collation 규칙을 사용하려면 다음 코드 조각을 사용할 수 있어요.

CREATE TABLE strings (s VARCHAR COLLATE DE);
INSERT INTO strings VALUES ('Gabel'), ('Göbel'), ('Goethe'), ('Goldmann'), ('Göthe'), ('Götz');
SELECT * FROM strings ORDER BY s;
"Gabel", "Göbel", "Goethe", "Goldmann", "Göthe", "Götz"

더 알아보기 (Learn more)

  • ICU 확장 문서에서 ICU collations를 확인해요.