Databricksのコレーションのご紹介

[Introducing Collations to Databricks \| Databricks Blog](https://www.databricks.com/blog/introducing-collations-databricks)の翻訳です。

:::note warn
本書は著者が手動で翻訳したものであり内容の正確性を保証するものではありません。正確な内容に関しては原文を参照ください。
:::

# データ処理における言語の違いを容易に考慮

:::note info
**サマリー**
- コレーション(collation)によって、100以上の言語における言語、コンテキストを考慮したデータベースを実現し、ユーザーが期待した通りにテキストを取り扱えるようにします。
- 英語名を検索するための大文字小文字を区別しない比較、非英語言語のアルファベットの並び替え、アクセントが重視される検索のようなタスクでコレーションを使用します。
- 大文字小文字を区別しない結果を得るための従来の方法と比較して、最大22倍高速になりました。
:::

```sql
SELECT 'Hello world!' COLLATE UNICODE,
       'Zdravo svete!' COLLATE SR,
       'Γειά σου, Κόσμε!' COLLATE EL,
       'Здравствуй, мир!' COLLATE RU,
       '你好, 世界!' COLLATE ZH,
       'Bonjour le monde!' COLLATE FR,
       'Hallo, Wereld!' COLLATE NL,
       'Hallo Welt!' COLLATE DE;
```

グローバル企業のアプリケーション構築は、多様な言語と一貫性のないデータエントリーの取り扱いを意味します。ドイツ語の"Apfel"の後の"Äpfel"のソートや、フランス語の"c"としての"ç"の取り扱いをどのようにしたらいいのでしょうか？また、ユーザーが入力した"John Smith"や"john smith"をどのように取り扱い、これらが同一であるとどのように結論づけるのでしょうか？

コレーションは、言語や大文字小文字を考慮する方法でテキストの並び替えや比較に関するルールを定義することでデータ処理を円滑にします。コレーションによって、データベースが言語、コンテキストを考慮するようになり、ユーザーが期待するようにテキストを取り扱うようになります。

Databricksランタイム16.1(まもなく、[Databricks SQL](https://www.databricks.com/jp/product/databricks-sql)のバージョン2024.50のプレビューチャネルと[Databricks Delta Live Tables](https://www.databricks.com/jp/product/delta-live-tables)でも)において、コレーションがパブリックプレビューで利用できることを共有できて嬉しく思っています。[コレーション](https://docs.databricks.com/en/sql/language-manual/sql-ref-collation.html)は、大文字小文字の区別やアクセントの区別のような、特定の言語の要件に合わせた文字列比較ルールを定義するための仕組みを提供します。この記事では、コレーションの動作原理、なぜ重要なのか、あなたの要件に合わせて適切なものをどのように選択すべきなのかについて探索します。

コレーションによって、ユーザーは自身のワークフローで実装するための、100以上の言語固有のコレーションルールから選択することができ、複数言語テキストデータベースにおけるソート、検索、結合のようなオペレーションを促進することができます。コレーションのサポートによって、レガシーデータベースシステムから移行を行う際に同じルールを容易に適用できるようになります。この機能は、大文字小文字やアクセントを区別しない比較を必要とする一般的なクエリーでは特に、パフォーマンスを劇的に改善しコードをシンプルにします。

# コレーションサポートの主要な機能

Databricksのコレーションのサポートには以下が含まれています:

- 大文字小文字やアクセントのバリエーションを持つ100以上の言語
- 100以上のSparkとSQLのエクスプレッション
- すべてのデータ操作との互換性(ジョイン、ソート、集計、クラスタリングなど)
- Photon最適化実装
- データスキッピング、z-order、リキッドクラスタリング、動的パーティション、ファイルプルーニングのようなパフォーマンス最適化を含むDeltaテーブルのネイティブサポート
- レガシーデータベースシステムからの移行の簡素化

コレーションのサポートは完全にオープンソース化されており、Apache Spark™とDelta Lakeにインテグレーションされています。

# あなたのクエリーでコレーションを使う

コレーションは、確立されているSparkの機能と堅牢なインテグレーションを提供しており、コレーションが適用されたデータでシームレスに機能するように、join、集計、ウィンドウ関数、フィルタリングのようなオペレーションが可能となっています。ほとんどの文字列表現はコレーションと互換性があり、`CONTAINS`、`STARTSWITH`、`REPLACE`、`TRIM`などの様々なエクスプレッションを活用することができます。コレーションの詳細は[ドキュメント](https://docs.databricks.com/en/sql/language-manual/sql-ref-collation.html)をご覧ください。

# コレーションによる一般的なタスクの解決

コレーションを使い始めるには、適切なコレーションを持つテーブルのカラムを作成(変更)します。ギリシャ語の名前では`EL_AI`コレーションを使うことになるでしょう。ここで、`EL`はギリシャ語の言語IDであり、`AI`はアクセントを区別しない(accent-insensitive)であることを意味します。(アクセントを持たない)英語名では、`UTF8_LCASE`を使うことになるで粗油。

コレーションによって解放されるシナリオを説明するために、以下のタスクを実行してみましょう:

- 英語名を特定するために大文字小文字を区別しない比較を用いる
- ギリシャ名をソートするために、ギリシャアルファベットの並び替えを使う
- アクセントを考慮しない方法でギリシャ名を検索する

デモンストレーションのために、ギリシャ語と英語両方のホメロスによる*イーリアス*の英雄の名前を格納するテーブルを使用します:

```sql
CREATE TABLE HeroNames (
    GreekName STRING COLLATE EL_AI,
    EnglishName STRING COLLATE UTF8_LCASE
);
INSERT INTO HeroNames (GreekName, EnglishName)
VALUES 
    ('Ἀχιλλεύς', 'Achilles'),
    ('Ἀγαμέμνων', 'Agamemnon'),
    ('Ὀδυσσεύς', 'Odysseus'),
    ('Διομήδης', 'Diomedes'),
    ('Αἴας ὁ Μέγας', 'Ajax the Greater'),
    ('Αἴας ὁ Λοκρός', 'Ajax the Lesser'),
    ('Μενέλαος', 'Menelaus'),
    ('Νέστωρ', 'Nestor'),
    ('Πάτροκλος', 'Patroclus'),
    ('Ἰδομενεύς', 'Idomeneus'),
    ('Ἕκτωρ', 'Hector'),
    ('Αἰνείας', 'Aeneas'),
    ('Πάρις', 'Paris'),
    ('Σαρπηδών', 'Sarpedon'),
    ('Γλαῦκος', 'Glaucus'),
    ('Πολυδάμας', 'Polydamas'),
    ('Πάνδαρος', 'Pandarus'),
    ('Δηίφοβος', 'Deiphobus'),
    ('Ἀντήνωρ', 'Antenor'),
    ('Αἰσύητης', 'Aesyetes');
```

*利用可能なコレーションを一覧するために、テーブル値関数をクエリーすることができます - `SELECT * FROM collations()`*

以降のクエリーでデータスキッピングを活用できるように、`ALTER`コマンドの後に`ANALYZE`コマンドを実行すべきです。

```sql
ANALYZE TABLE HeroNames COMPUTE STATISTICS FOR COLUMNS GreekName, EnglishName;
```

これで、英語名を比較する際に明示的に`LOWER`を使う必要がなくなりました。また、内部ではファイルプルーニングも実行されます。

```sql
SELECT * FROM HeroNames WHERE EnglishName = 'achilles';

+---------+-----------+
|GreekName|EnglishName|
+---------+-----------+
| Ἀχιλλεύς|   Achilles|
+---------+-----------+
```

ギリシャ語のルールに沿ってソートを行うには、シンプルに`ORDER BY`を使います。`EL_AI`コレーションなしにソートした結果と異なることに注意してください。

```sql
SELECT * FROM HeroNames ORDER BY GreekName;

+-------------+----------------+
|    GreekName|     EnglishName|
+-------------+----------------+
|    Ἀγαμέμνων|       Agamemnon|
|Αἴας ὁ Λοκρός| Ajax the Lesser|
| Αἴας ὁ Μέγας|Ajax the Greater|
|      Αἰνείας|          Aeneas|
|     Αἰσύητης|        Aesyetes|
|      Ἀντήνωρ|         Antenor|
|     Ἀχιλλεύς|        Achilles|
|      Γλαῦκος|         Glaucus|
|     Δηίφοβος|       Deiphobus|
|     Διομήδης|        Diomedes|
|        Ἕκτωρ|          Hector|
|    Ἰδομενεύς|       Idomeneus|
|     Μενέλαος|        Menelaus|
|       Νέστωρ|          Nestor|
|     Ὀδυσσεύς|        Odysseus|
|     Πάνδαρος|        Pandarus|
|        Πάρις|           Paris|
|    Πάτροκλος|       Patroclus|
|    Πολυδάμας|       Polydamas|
|     Σαρπηδών|        Sarpedon|
+-------------+----------------+
```

そして、検索においてアクセントを区別しない方法で行う場合には、例えばAgamemnon(ギリシャ語でἈγαμέμνων)を含む全ての行を取得するには、ギリシャ語のアクセントありバージョンにマッチするフィルターを適用するだけで大丈夫です。

```sql
SELECT * FROM HeroNames WHERE GreekName = 'Αγαμεμνων';

+---------+-----------+
|GreekName|EnglishName|
+---------+-----------+
|Ἀγαμέμνων|  Agamemnon|
+---------+-----------+
```

# コレーションによるパフォーマンス

コレーションのサポートによって、大文字小文字を区別しない結果を得るために、高コストのオペレーションを実行する必要がなくなり、処理を円滑にし、効率性を高めます。以下のグラフでは、大文字小文字を区別しない結果を得るためにSQL関数`LOWER`を用いた際の実行時間と、コレーションサポートを用いた際の実行時間を比較しています。この比較は、ランダムに生成された10億の文字列に対して行われています。ここでのクエリーは、カラム`col`に対して大文字小文字を区別せずに`abc`に等しいすべての文字列をフィルタリングすることを目的としています。レガシーの`UTF8_BINARY`コレーションが使われるシナリオにおいては、フィルター条件は`LOWER(col) == ‘abc’`となります。`col`に`UTF8_LCASE`コレーションが適用されると、フィルター条件はシンプルに`col == ‘abc’`となり、同じ結果を得ることができます。コレーションを用いることで、Deltaのファイルスキッピングを活用することによって、最大で**22倍高速なクエリー処理**を実現しています(この場合、どちらのケースでもPhotonは使われていません)。

![](https://www.databricks.com/sites/default/files/inline-images/image1_45.png?v=1736543868)

Photonを用いることで、パフォーマンス改善はさらに大きなものになります(*実際のスピードは使用されるコレーション、関数、データによって変動します*)。以下のグラフでは、`UTF8_LCASE`コレーションを用いて、同値比較、`STARTSWITH`、`ENDSWITH`、`CONTAINS`のSQL関数におけるPhotonありなしのスピードを示しています。これらの関数はランダムに生成されたASCIIのみの1000文字のデータセットに対して実行されました。この例では、`STARTSWITH`と`ENDSWITH`では、コレーションを用いた際に**10倍のスピードアップ**という結果になっています。

![](https://www.databricks.com/sites/default/files/inline-images/image3_39.png?v=1736543868)

Photon最適化実装を除き、すべてのコレーション機能はオープンソースSparkでも利用できます。データフォーマットの変更は無く、これは背後のフィールドのはUTF-8エンコードされたデータのままであることを意味し、すべての機能はオープンソースSparkとDelta Lakeの両方でサポートされることを意味します。これは、お客様はロックインされず、Sparkエコシステムで自分たちのコードの可搬性のあるものとしてみなせることを意味します。

# 次に来るのは

近い将来、お客様はカタログ、スキーマ、テーブルレベルでコレーションを設定できるようになります。まもなく、`RTRIM`もサポートされ、不必要な末尾の空白を無視した文字列比較が可能になります。アップデートに関しては、Databricksのホームページやドキュメントページの[今後の予定](https://docs.databricks.com/ja/whats-coming.html)を注視していてください。

# 使い始める

コレーションを使い始めるには、Databricksの[ドキュメント](https://docs.databricks.com/en/sql/language-manual/sql-ref-collation.html)をご覧ください。

Databricks SQLの詳細に関しては、[Webサイト](https://www.databricks.com/jp/product/databricks-sql)や[ドキュメント](https://docs.databricks.com/ja/sql/index.html)をご覧ください。[Databricks SQLの製品ツアー](https://www.databricks.com/resources/demos/tours/governance/dbsql?itm_data=demo_center)をチェックすることもできます。あなたの既存のウェアハウスを、優れたユーザー体験と安価なコストを提供する高性能でサーバレスなデータウェアハウスに移行したいと考えているのであれば、Databricks SQLがソリューションとなります。[無料で試してみましょう](https://databricks.com/jp/try-databricks)。

### はじめてのDatabricks

[はじめてのDatabricks](https://qiita.com/taka_yayoi/items/8dc72d083edb879a5e5d)

### Databricks無料トライアル

[Databricks無料トライアル](https://databricks.com/jp/try-databricks)