# MySQL照合順序を検索とUNIQUE制約で選ぶ全角・半角の実例

> MySQL 8.4の照合順序を、等価比較とUNIQUEで同じ判定になる範囲と、LIKE検索で結果が食い違う範囲に分けて実機の値で整理します。全角・半角、かな、濁点、結合文字、末尾スペース、商品名やログインIDの設計、既存DB移行の確認SQLも示します。

Canonical URL: https://labs.eastbraver.com/blog/mysql-collation-unique-width
Published: 2026-09-19T19:54:00+09:00
Updated: 2026-09-25T07:16:42+09:00
Category: infrastructure
Tags: software-engineering

`Cafe` が登録されているカラムに、`Café` をもう1件保存できるでしょうか。
`商品(赤)` と `商品（赤）`、`カナ` と `ｶﾅ` ではどうでしょう。

MySQLでは、照合順序とUNIQUE制約によって結果が変わります。
検索で同じものとして見つけたい表記を、登録時にも重複として扱ってよいか。
商品名、ログインID、外部サービスのIDで、ここを決める必要があります。

照合順序を選ぶときは、検索の使いやすさだけでは足りません。
`=` で同じ値とみなす範囲が、そのまま登録を拒否する範囲になります。
さらに、実際の検索でよく使う `LIKE` は `=` とは別の規則で動くため、同じカラムでも結果が食い違う組があります。

対象はMySQL 8.4とInnoDBです。
比較基準は標準設定の `utf8mb4_0900_ai_ci` とします。
本記事の比較表は、断りのない限り `=` の結果です。
UNIQUE制約の重複判定、`DISTINCT`、`GROUP BY` は、この `=` と同じ規則で動きます。
`LIKE` は1コードポイントずつ比較する別の判定なので、該当する節で結果を分けて示します。
以下の登録例は、入力時の変換をせず、`VARCHAR` カラム全体に単一カラムのUNIQUE制約を設定した場合です。
通常の `INSERT` を前提にし、別の条件はその都度記載します。

## 照合順序で同じ値になる範囲

基準の `utf8mb4_0900_ai_ci` で、次の組をそれぞれ両方登録できるでしょうか。

| 1件目 | 2件目 | 両方登録できるか | 理由 |
|---|---|---:|---|
| `Cafe` | `café` | できない | 大文字小文字とアクセントを区別しない |
| `商品(赤)` | `商品（赤）` | できない | 括弧の幅を区別しない |
| `カナ` | `ｶﾅ` | できない | カタカナの幅を区別しない |
| `かな` | `カナ` | できない | ひらがなとカタカナを区別しない |
| `は` | `ば` | できない | 濁点を区別しない |
| `つ` | `っ` | できない | 小書き文字を区別しない |
| `ABC` | `ABC `（末尾に半角スペース） | できる | `0900` 系は `NO PAD` |

答えは、最後の末尾スペースの組み合わせだけ登録できます。
それ以外の組み合わせは照合上同等となり、2件目が重複エラーになります。

大文字小文字だけでなく、括弧の幅、かなの種類、濁点、小書き文字にも違いが出ます。
名前に付いた `ai_ci` だけを見て、英字にしか関係しない設定だと判断すると、ここを見落とします。

この7組は、実機では `LIKE` でも `=` と同じ結果になりました。
ただし、濁点付きの半角カタカナや合字のように、`=` と `LIKE` が食い違う組もあります。
その差は後述の「検索式と並べ替え」で扱います。

### 文字セットと照合順序

文字セットは、文字をどのように符号化して保存するかを決めます。
照合順序は、文字列の等価判定や並べ替えに使うルールです。

| 選択 | 決めること | 確認例 |
|---|---|---|
| 文字セット | 保存できる文字と符号化 | `utf8mb3` か `utf8mb4` か |
| 照合順序 | 等価判定と並べ替え | `e = é` か、`A = a` か |
| 接続設定 | アプリケーションとの受け渡し | client、connection、resultsの文字セット |

MySQL 8.4の `utf8` は、最大3バイトの `utf8mb3` の別名です。
「吉」は保存できますが、「𠮷」や絵文字の「😀」のようにUTF-8で4バイト必要な文字は保存できません。
絵文字すべてが対象なのではなく、補助平面にある文字が対象です。

新規開発では `utf8mb4` を選びます。
`utf8mb3` は非推奨です。
また、`utf8mb4` にしてもすべての文字が4バイトになるわけではありません。
例えばASCIIの `A` は1バイトのままです。
保存範囲と非推奨指定はMySQL公式の[`utf8mb3`の説明](https://dev.mysql.com/doc/refman/8.4/en/charset-unicode-utf8mb3.html)と[`utf8mb4`の説明](https://dev.mysql.com/doc/refman/8.4/en/charset-unicode-utf8mb4.html)で確認できます。

カラムが `utf8mb4` でも、アプリケーションとの接続が対応していなければ、文字の受け渡しで問題が起きます。
DBの定義と[接続文字セット](https://dev.mysql.com/doc/refman/8.4/en/charset-connection.html)の両方を確認します。
実機確認では、`utf8mb4` カラムへUTF-8の `商品` を `latin1` 接続から送ると、`C3A5E280A2E280A0C3A5E2809CC281` という15バイトで保存されました。
書き込みと読み出しに同じ誤設定を使うと正しく見える場合もあります。
カラム定義だけでなく、接続設定まで確認する理由がここにあります。

`utf8mb4_0900_ai_ci` は次のように読めます。

* `utf8mb4`：文字セット。
* `0900`：Unicode照合アルゴリズム（UCA）9.0に基づく比較ルール。
* `ai`：アクセントを区別しない。例えば `e = é`。
* `ci`：大文字小文字を区別しない。例えば `A = a`。

`as` はアクセントを区別する指定、`cs` は大文字小文字を区別する指定です。
日本語向けの `ks` は、ひらがなとカタカナを区別します。

`0900` は保存できる文字をUnicode 9.0までに制限する指定ではありません。
また、照合順序を設定しても、保存した `Café` が `cafe` に書き換わることはありません。

照合順序の名前は自由に組み立てられません。
例えば `utf8mb4_0900_ai_cs` はMySQL 8.4に存在しません。
`utf8general_ci` や `utf8mb4_general` も正式な照合順序名ではありません。
命名規則はMySQL公式の[Collation Naming Conventions](https://dev.mysql.com/doc/refman/8.4/en/charset-collation-names.html)を参照し、実際に利用できる名前は `SHOW COLLATION` で確認します。

### 商品名や記事タイトルの検索

`cafe` で検索して `Cafe` や `Café` も見つけたいなら、`utf8mb4_0900_ai_ci` が候補です。

> [!IMPORTANT] 等価比較とUNIQUEの判定を検索条件と分ける
> このカラムの照合順序による `=` 比較で同等になる値は 同じカラム全体に設定した単一カラムのUNIQUE制約でも重複と判定される
>
> ただしUNIQUEで重複と判定される組が `LIKE` 検索で互いに見つかるとは限らない
>
> 検索式に別の照合順序を指定する場合や `LIKE`・正規表現・全文検索を使う場合は 検索の一致条件とUNIQUEの判定を分けて確認する
>
> この `utf8mb4_0900_ai_ci` のカラムで `Cafe` と `Café` を別々に残すなら この照合順序のまま単一カラムのUNIQUE制約を付ける設計は使えない

この設定のカラムでは、`WHERE name = 'cafe'` に `Café` が一致します。
`WHERE name LIKE 'cafe%'` でも `Café Latte` の行が一致します。
UNIQUE制約がなければ、`Cafe` と `Café` を別々の行に保存し、同じ検索条件で両方を取得できます。

一方、同じカラムでも `=` と `LIKE` の結果が一致しない組があります。
`utf8mb4_0900_ai_ci` の `name` カラムに次の9行を入れて確かめました。

| id | `name` |
|---:|---|
| 1 | `ガイドブック` |
| 2 | `ｶﾞｲﾄﾞﾌﾞｯｸ` |
| 3 | `カナ手帳` |
| 4 | `ｶﾅ手帳` |
| 5 | `Café Latte` |
| 6 | `(株)東` |
| 7 | `㈱東` |
| 8 | `ABC `（末尾に半角スペース） |
| 9 | `ABC` |

| 検索条件 | 一致したid |
|---|---|
| `name = 'ガイドブック'` | 1・2 |
| `name LIKE 'ガイドブック'` | 1 |
| `name LIKE 'ガイド%'` | 1 |
| `name LIKE '%ｶﾞｲﾄﾞ%'` | 2 |
| `name LIKE 'カナ%'` | 3・4 |
| `name LIKE 'cafe%'` | 5 |
| `name = '(株)東'` | 6・7 |
| `name LIKE '(株)%'` | 6 |
| `name = 'ABC'` | 9 |
| `name LIKE 'ABC'` | 9 |

濁点のない `カナ手帳` と `ｶﾅ手帳` は、`=` でも `LIKE` でも同じ扱いです。
ところが `ガイドブック` と `ｶﾞｲﾄﾞﾌﾞｯｸ` は、`=` で同等と判定されるのに、前方一致でも部分一致でも互いを見つけられません。
`(株)東` と `㈱東` も同じ形です。
UNIQUE制約を付ければ2件目の登録は重複として拒否されるのに、検索では別の商品のように振る舞います。
理由は後述の「検索式と並べ替え」で扱います。

末尾スペースの `ABC ` は、`0900` 系が `NO PAD` のため `ABC` と別の値です。
`=` でも `LIKE` でもid 9だけが返ります。

UNIQUE制約を付けると、登録にも同じ比較規則を使います。
同名の商品を許可するなら、商品名にはUNIQUEを付けず、商品IDや商品コードで識別します。

日本語では、基準の設定が `は`・`ば`・`ぱ` まで同一視する点に注意が必要です。
日本語の検索を扱う際は、幅やかなだけでなく、濁点と小書き文字も含めて選びます。

### 全角・半角とひらがな・カタカナ

日本語の入力では、少なくとも文字の幅、かなの種類、濁点、小書き文字を分けて確認します。
以下は、挙げた文字列を `=` で比較した場合です。
同等になる組み合わせは、UNIQUE付きのカラムへ両方は登録できません。

| 照合順序 | `Cafe` / `cafe` | `cafe` / `café` | `()` / `（）` | `かな` / `カナ` | `カナ` / `ｶﾅ` | `は` / `ば` | `つ` / `っ` |
|---|---:|---:|---:|---:|---:|---:|---:|
| `utf8mb4_0900_ai_ci` | 同等 | 同等 | 同等 | 同等 | 同等 | 同等 | 同等 |
| `utf8mb4_0900_as_ci` | 同等 | 異なる | 同等 | 同等 | 同等 | 異なる | 同等 |
| `utf8mb4_0900_as_cs` | 異なる | 異なる | 異なる | 異なる | 異なる | 異なる | 異なる |
| `utf8mb4_ja_0900_as_cs` | 異なる | 異なる | 同等 | 同等 | 同等 | 異なる | 異なる |
| `utf8mb4_ja_0900_as_cs_ks` | 異なる | 異なる | 同等 | 異なる | 同等 | 異なる | 異なる |

この比較は、MySQLが説明する[UCA 9.0照合の比較レベル](https://dev.mysql.com/worklog/task/?id=10818)、Unicodeの[UCA 9.0.0照合データ](https://www.unicode.org/Public/UCA/9.0.0/allkeys.txt)、MySQL 8.4.11ソースの[日本語向け照合データ](https://github.com/mysql/mysql-server/blob/99960bf74fa919347e4f4e3ca47672f333d6e91f/strings/uca900_ja_data.h)から導き、後述の実機検証と照合した値です。

同じ35セルを `LIKE` でも実行したところ、34セルは `=` と同じ結果でした。
食い違ったのは `utf8mb4_ja_0900_as_cs_ks` の `かな` / `カナ` の1セルだけです。
この1セルは `=` で異なり、`LIKE` では一致します。

**`utf8mb4_0900_ai_ci`**

`商品(赤)` と `商品（赤）`、`ABC123` と `ＡＢＣ１２３` は同等です。
`かな`・`カナ`・`ｶﾅ` も同一視します。
さらに `は`・`ば`・`ぱ`、`つ` と `っ` も区別しません。
幅を吸収したいという理由だけで選ぶと、残したかった日本語の違いまで失う場合があります。

**`utf8mb4_0900_as_ci`**

括弧や英数字の幅、`かな`・`カナ`・`ｶﾅ` は引き続き同一視します。
大文字小文字も区別しません。
一方、アクセントと濁点は区別するため、`cafe` と `café`、`は`・`ば`・`ぱ` は別々に登録できます。
ただし `つ` と `っ` はまだ同等です。
`as` を付ければ日本語の違いをすべて保てるわけではありません。

**`utf8mb4_0900_as_cs`**

`Cafe` と `cafe`、`cafe` と `café` を区別します。
ここに挙げた括弧や英数字の幅も区別し、`かな`・`カナ`・`ｶﾅ`、`つ` と `っ` もそれぞれ別の値になります。
これらはUNIQUE付きでも別々に登録できます。
ただし、言語的な照合であることは変わりません。
後述する結合文字や無視される文字まで、すべてバイト単位で区別する指定ではありません。

**`utf8mb4_ja_0900_as_cs`**

日本語向けの照合順序です。
濁点、小書き文字、英字の大文字小文字を区別しながら、`かな`・`カナ`・`ｶﾅ` は同等に扱います。

`商品(赤)` と `商品（赤）`、`ABC123` と `ＡＢＣ１２３` も同等です。
したがって、これらの幅違いはUNIQUE付きでは両方登録できません。
`ja` のない `utf8mb4_0900_as_cs` とは結果が異なります。

読み仮名の検索で、かなの種類を吸収し、濁点や小書き文字は残したい場合の候補です。
ただし英字の大文字小文字も区別するため、英字を混ぜる検索ではその要件も確認します。

**`utf8mb4_ja_0900_as_cs_ks`**

上記に、ひらがなとカタカナの区別が加わります。
`かな` と `カナ` は別々に登録できますが、`カナ` と `ｶﾅ` は同等です。
括弧と英数字の幅も引き続き同一視します。
`ks` は全角・半角を区別する指定ではありません。
`ci` や `ks` の略語だけから、幅の扱いを判断しないようにします。

ただし、この `ks` のかな区別は `LIKE` には効きません。

| 式（`utf8mb4_ja_0900_as_cs_ks`） | 結果 |
|---|---|
| `'かな' = 'カナ'` | 異なる |
| `'かな' LIKE 'カナ'`（逆方向・前方一致・部分一致も同じ） | 一致する |
| UNIQUE付きカラムへ `かな` と `カナ` を登録 | 両方登録できる |
| 索引を使わない `WHERE v LIKE 'かな'` | `かな` と `カナ` の両方 |
| `LIKE` での `つ` / `っ`・`は` / `ば`・`A` / `a` | 一致しない |

`ks` は `=`・UNIQUE・並べ替えに効く指定であり、`LIKE` には効きません。
`ks` の他の区別は `LIKE` でも保たれるため、かなの種類だけが例外です。
読み仮名でひらがなとカタカナを分けたい要件を `ks` と `LIKE` の組み合わせで満たすことはできません。

Unicodeには、半角カタカナに対応する標準の半角ひらがな一式はありません。
`ぁ` や `っ` は小書きのひらがなであり、半角文字ではありません。
フォント上の表示幅と、別の文字として符号化されているかどうかも別の話です。
文字の分類はUnicodeの[Halfwidth and Fullwidth Forms](https://www.unicode.org/charts/PDF/UFF00.pdf)と[Hiragana](https://www.unicode.org/charts/PDF/U3040.pdf)で確認できます。

濁点付きの入力では、`ガ`・半角の `ｶﾞ`・`カ` と結合濁点 `U+3099` を並べた表現も分けて確認します。
見た目が近くても、`ガ` は1コードポイントで、残りの2例は2コードポイントです。

| 照合順序 | `ガ` / `ｶﾞ` | `ガ` / `カ`+`U+3099` | `ｶﾞ` / `カ`+`U+3099` |
|---|---:|---:|---:|
| `utf8mb4_0900_ai_ci` | 同等 | 同等 | 同等 |
| `utf8mb4_0900_as_ci` | 同等 | 同等 | 同等 |
| `utf8mb4_0900_as_cs` | 異なる | 同等 | 異なる |
| `utf8mb4_ja_0900_as_cs` | 異なる | 同等 | 異なる |
| `utf8mb4_ja_0900_as_cs_ks` | 異なる | 同等 | 異なる |
| `utf8mb4_0900_bin` | 異なる | 異なる | 異なる |

同じ3組を `LIKE` で比較すると、結果が変わります。

| 照合順序 | `ガ` / `ｶﾞ` | `ガ` / `カ`+`U+3099` | `ｶﾞ` / `カ`+`U+3099` |
|---|---:|---:|---:|
| `utf8mb4_0900_ai_ci` | 一致しない | 一致しない | 一致する |
| `utf8mb4_0900_as_ci` | 一致しない | 一致しない | 一致する |
| `utf8mb4_0900_as_cs` | 一致しない | 一致しない | 一致しない |
| `utf8mb4_ja_0900_as_cs` | 一致しない | 一致しない | 一致しない |
| `utf8mb4_ja_0900_as_cs_ks` | 一致しない | 一致しない | 一致しない |
| `utf8mb4_0900_bin` | 一致しない | 一致しない | 一致しない |

`=` で同等だったセルのうち、`LIKE` でも一致するのは、`ｶﾞ` / `カ`+`U+3099` を `ai_ci` と `as_ci` で比べた2セルだけです。
この組では両辺が2コードポイントずつで対応し `ai_ci` と `as_ci` の文字ごとの比較でも各位置が一致する
同じ長さでも `as_cs` や日本語向け照合順序では一致しないため コードポイント数だけで結果は決まらない

MySQL 8.4.11で `=` と通常の2回の `INSERT` を実行し、表の全組で同じ結果を確認しました。
`パ`・`ﾊﾟ`・`ハ`+`U+309A` でも同じ傾向です。

ここで確認した合成済み文字と単一の結合文字の組は、`as_cs` や日本語照合の `=` でも同等になります。
ただし、これを正準等価一般の性質として読んではいけません。
MySQLは入力を正規化せず、照合データ上の分解によって結果的に吸収しているだけです。
反例として、結合文字の順序だけが違う `a`+`U+0323`+`U+0307` と `a`+`U+0307`+`U+0323` は正準等価ですが、実機では `utf8mb4_0900_ai_ci` で同等、`utf8mb4_0900_as_ci` と `utf8mb4_0900_as_cs` では異なる値でした。
そのうえ、合成済み文字と結合列の組は `=` で同等でも `LIKE` では一致しません。

`カナ` と `ｶﾅ` が同等でも、`ガ` と `ｶﾞ` まで同等になるとは限らない点が重要です。
さらに `ガ` と `ｶﾞ` は、`ai_ci` でも `LIKE` では一致しません。
`=` の同等性を、そのまま検索の期待値として使うことはできません。

幅を統一して検索する仕様なら 保存する原文とは別に検索キーを作り 半角カタカナや結合文字の変換規則を定義する
保存する検索キーと検索入力の両方に同じ正規化・表記変換を適用し 同一視したい表記を共通の表現に揃える
コードポイント数を揃えるだけでは `LIKE` の一致は保証されない
変換後の値と実際に使う `LIKE` パターンで 期待する行が見つかることを確認する
入力中の `%` と `_` を通常の文字として検索する場合は 正規化・表記変換の後にエスケープする
同姓同名の人を許可するため、氏名そのものを一意な識別子にはしません。
また、照合順序は漢字氏名の読みを判断しないため、名簿を五十音順に並べるなら、確認済みの読み仮名を別カラムに保存して並べ替えます。

## 用途別に識別子を設計する

人が読む名前と識別子では、同一視してよい文字の範囲が違います。
商品コードや外部サービスのIDで `AbC123` と `abc123` を別のIDとして扱うなら、UTF-8の文字列には `VARCHAR` と `utf8mb4_0900_bin` が候補です。

| 比較例 | `utf8mb4_0900_bin` | UNIQUE付きで両方登録できるか |
|---|---|---:|
| `AbC123` と `abc123` | 異なる | できる |
| `ABC` と `ＡＢＣ` | 異なる | できる |
| `カナ` と `ｶﾅ` | 異なる | できる |
| `ABC` と `ABC `（末尾に半角スペース） | 異なる | できる |
| 同じUTF-8文字列 | 同じ | できない |

内部の商品コードで空白を許可したくないなら、入力時に拒否するか、除去する規則を別に決めます。
外部サービスのIDについては発行元の仕様に従い、大文字小文字を区別するIDを受け取り側で勝手に小文字化しないようにします。

`_bin` 系の比較方法を、別の文字セットへそのまま一般化することはできません。
ここで扱う `utf8mb4_0900_bin` はUTF-8の符号化バイトを重みに使い、`utf8mb4_bin` と同じ文字の並び順になります。
バイナリ型との違いはMySQL公式の[binary照合と`_bin`照合の説明](https://dev.mysql.com/doc/refman/8.4/en/charset-binary-collations.html)で確認できます。

### ログインID

例えば、ASCII英数字とアンダースコアだけを許可し、大文字小文字を区別しないログインIDを作るとします。

1. 入力を許可文字で検査する。
2. ASCII英字を小文字へ統一する。
3. 変換後の値を `login_id_key` に保存する。
4. `login_id_key` を `utf8mb4_0900_bin`、`NOT NULL`、UNIQUE制約付きにする。
5. 重複エラーをアプリケーションで扱う。

`Alice`、`alice`、`ALICE` は同じ `alice` に変換されます。
最初の1件を登録した後は、残りの表記も同じキーになるため、重複エラーになります。
画面では入力された大文字小文字を残したければ、表示用の値を別カラムに持たせます。

登録前のSELECTだけで重複を防ぐ設計にはしません。
同時登録では、二つの処理がどちらも未登録と判断する可能性があります。
DBのUNIQUE制約で最後の重複を防ぎ、アプリケーションでエラーを扱います。

Unicodeを広く許可するIDでは、正規化に加え、見た目が似た別の文字や不可視文字への対応も決めます。
ラテン文字の `a` とキリル文字の `а` のような混同は、照合順序だけで解決する問題ではありません。
識別子の混同対策はUnicodeの[Security Mechanisms](https://www.unicode.org/reports/tr39/)も参照します。

### メールアドレス

メール配送の仕様と、サービスのアカウント登録規則は分けて定めます。

| 対象 | 仕様上の扱い | アカウント設計で決めること |
|---|---|---|
| ドメイン部分 | 大文字小文字を区別しない | 小文字化などの正規化 |
| ローカル部分 | 大文字小文字を保持し、宛先側の解釈を尊重する | サービス内で同一視する範囲 |
| 配送用アドレス | 宛先へ渡す原文 | 原文を失わず保存する方法 |
| 一意判定キー | SMTPの配送仕様とは別 | 明文化した変換とUNIQUE制約 |

メールアドレス全体を `utf8mb4_0900_ai_ci` にし、UNIQUE制約を付けると、`User@example.com` の後に `user@example.com` は登録できません。
アクセントも区別しないため、Unicodeのアドレスを許可する設計では、その同一視も発生します。

SMTPの扱いは[RFC 5321の2.3.11と2.4](https://www.rfc-editor.org/rfc/rfc5321.html)で確認できます。
配送用のアドレスを保持し、アカウントの一意判定に変換が必要なら、その規則を明文化した別のキーを用意します。
ドットの除去や `+` 以降の削除を、すべてのメールサービスに共通する処理として適用してはいけません。

### ハッシュ値などのバイト列

生のバイト列とUTF-8文字列は、用途に合わせて型を分けます。

| 保存対象 | 型の候補 | 比較と注意点 |
|---|---|---|
| 任意の生バイト列 | `VARBINARY` | バイト値で比較する |
| 有効なUTF-8文字列 | `VARCHAR ... COLLATE utf8mb4_0900_bin` | 文字セットの検査や変換が関わる |
| 固定長のバイト列 | `BINARY(N)` | 足りない部分が `0x00` で埋められる |
| 16進数表現 | 文字列型 | 同じ値を大文字と小文字の両方で書ける |
| Base64またはBase64url表現 | 文字列型 | 大文字小文字が別の値を表す |

`VARBINARY` はバイト値で比較し、UNIQUE付きなら同じバイト列の再登録を拒否します。
`VARCHAR ... COLLATE utf8mb4_0900_bin` は任意のバイトを保存する型ではありません。
型ごとの保存と比較の違いはMySQL公式の[BINARY and VARBINARY](https://dev.mysql.com/doc/refman/8.4/en/binary-varbinary.html)で確認できます。

Base64とBase64urlは大文字小文字を区別します。
例えば `AA==` と `aA==` はそれぞれ `0x00` と `0x68` を表します。
符号化文字列をそのまま比較または一意判定する場合は `utf8mb4_0900_bin` などを明示します。
復号後のバイト列として管理する場合は `VARBINARY` などを使用します。
16進数表現とは分けて設計します。
各符号化の規則は[RFC 4648](https://www.rfc-editor.org/rfc/rfc4648.html)で確認できます。

RFC 4648の[第8節](https://www.rfc-editor.org/rfc/rfc4648.html#section-8)は Base16を大文字小文字を区別しない標準的な16進符号化と説明している
アルファベット表は `A–F` を使っているが 大文字小文字によって復号後の値は変わらない
外部プロトコルが表記を指定する場合は その仕様に従う
両方の表記を受け付けて保存形式を統一するなら ASCIIの `0–9`・`A–F`・`a–f` と用途に応じた桁数を検査したうえで 大文字か小文字のどちらかに統一し `utf8mb4_0900_bin` を明示する
大文字小文字を吸収する目的で `utf8mb4_0900_ai_ci` を選ぶのは避けます。
この照合順序の実機では `ab12` と `ＡＢ１２` が同等になり、`deadbeef` と途中にゼロ幅スペースを挟んだ値も同等になりました。
識別子のつもりの列で、全角英数字や無視される文字まで重複判定に巻き込みます。
`ascii` 文字セットと `ascii_general_ci` も選択肢です。
`DEADBEEF` と `deadbeef` は同等になり、非ASCIIは `STRICT_TRANS_TABLES` を含む既定の `sql_mode` ではエラー1366で拒否されました。
ただし `sql_mode` を空にすると警告1366だけになり、`ＡＢ１２` は `????`（`0x3F3F3F3F`）として保存されます。
拒否に頼る設計では、文字セットだけでなく `sql_mode` も固定します。

## 保存と検索で判定がずれる場所

同じ文字列でも、保存、UNIQUE、`=`、`LIKE` が同じ規則で動くとは限りません。
まず `utf8mb4_bin` と `utf8mb4_0900_bin` を比べます。どちらも大文字小文字を区別しますが、前者は `PAD SPACE`、後者は `NO PAD` です。

| 条件 | `utf8mb4_bin` | `utf8mb4_0900_bin` |
|---|---|---|
| PAD属性 | `PAD SPACE` | `NO PAD` |
| `ABC` と `ABC `（末尾に半角スペース）の `=` | 同等 | 異なる |
| 同じ組の `LIKE` | 一致しない | 一致しない |
| UNIQUE付きの2件登録 | できない | できる |

`LIKE` の行に注目してください。
`PAD SPACE` の `utf8mb4_bin` では、UNIQUEで重複になる `ABC` と `ABC ` を `LIKE` では一致させられません。
`utf8mb4_general_ci` や `utf8mb4_unicode_ci` でも同じ結果でした。
`LIKE` は末尾スペースをPAD属性にかかわらず1文字として扱います。

今回扱った `general_ci`、`unicode_ci`、`unicode_520_ci` も `PAD SPACE`、`0900` 系は `NO PAD` です。
この属性は `INFORMATION_SCHEMA.COLLATIONS.PAD_ATTRIBUTE` で確認できます。

末尾に空白が存在するかどうかと、空白の幅を区別するかどうかは別の条件です。
`utf8mb4_0900_ai_ci` と日本語向けの `utf8mb4_ja_0900_as_cs` では、半角スペース `U+0020` と全角スペース `U+3000` を同等に扱います。
この組は `LIKE` でも一致します。
一方、`utf8mb4_0900_as_cs` は両者を区別します。
したがって `NO PAD` だからといって、すべての空白文字をバイト単位で区別するわけではありません。
入力仕様では、前後の空白、途中の空白、タブなどを分けて扱います。

`CHAR` では、保存時に定義長まで空白で埋め、取得時に末尾の空白を除去します。
`NO PAD` の照合順序を選んでも、`CHAR` カラムでは `ABC` と `ABC ` を別々に登録できません。
保存した末尾スペースを保持する必要があるなら、`VARCHAR` を使います。
詳しい挙動はMySQL公式の[CHAR and VARCHAR](https://dev.mysql.com/doc/refman/8.4/en/char.html)で確認できます。

空白を禁止したい設計では、照合順序に期待するより、入力検査で拒否する方が仕様を明確にできます。

### Unicode正規化と文字列の長さ

`é` は1コードポイントでも、`e` と結合アクセントを並べた2コードポイントでも表現できます。
正規化と照合順序と長さは、別々に確認します。

| 観点 | 例 | 注意点 |
|---|---|---|
| NFC | `é` と `e` + 結合アクセント | 正準等価な表現を統一する |
| NFKC | `Ａ → A`、`（ → (`、`ｶﾞ → ガ`、`① → 1` | 互換文字の区別も失う |
| `LENGTH()` | UTF-8のバイト数 | 画面上の文字数ではない |
| `CHAR_LENGTH()` | コードポイント数 | 書記素クラスタ数ではない。`LIKE` の `_` も同じ単位 |

NFKCは、幅を統一したいだけのつもりでも、丸数字などの区別まで失います。
ひらがなをカタカナへ変える処理でもありません。
正規化の定義はUnicodeの[Normalization Forms](https://www.unicode.org/reports/tr15/)で確認できます。

正規化処理を明示的に行わなくても、照合順序自体が互換文字を同一視する場合があります。
実機の `utf8mb4_0900_ai_ci` では、`(株)` / `㈱`・`No1` / `№1`・`fi` / `ﬁ`・`1` / `①`・`I` / `Ⅰ` がすべて同等となり、UNIQUE付きでは2件目がエラー1062になりました。
同じ組を `utf8mb4_ja_0900_as_cs` で確認すると、すべて異なる値です。
互換文字を一律に同一視する規則ではないため、実際に受け付ける組を列挙して確認します。

この5組は `LIKE` の扱いも割れます。

| 組 | `utf8mb4_0900_ai_ci` の `=` | 同じ照合順序の `LIKE` |
|---|---|---|
| `(株)` / `㈱` | 同等 | 一致しない |
| `No1` / `№1` | 同等 | 一致しない |
| `fi` / `ﬁ` | 同等 | 一致しない |
| `1` / `①` | 同等 | 一致する |
| `I` / `Ⅰ` | 同等 | 一致する |

`1` / `①` と `I` / `Ⅰ` はそれぞれ1文字同士の一次重みが一致するため `LIKE` でも一致する
`㈱`・`№`・`ﬁ` は1文字が複数文字に展開されるため、`LIKE` では一致しません。
互換文字は `LIKE` で一致しない、という一般化も成り立ちません。
結果として、UNIQUE制約でエラー1062になる組の一部は、`LIKE` 検索では相手を見つけられません。

原文の保存が必要な氏名や会社名では、原文を残し、検索キーに適用する変換を限定します。
一意判定用のキーを正規化する場合は、正規化後にUNIQUEを判定し、変換後の長さも検査します。

UCAの比較には、重みを持たず、照合上無視される文字があります。
例えばUCA 9.0では、ゼロ幅スペース `U+200B` や異体字セレクターにゼロの重みが定義されています。
そのため `as_cs` を、全コードポイントの違いを必ず区別する指定として使ってはいけません。
表現の違いそのものを保持して識別するなら、`utf8mb4_0900_bin` などと、保存前の変換方針を組み合わせます。

無視される文字でも、`=` と `LIKE` の扱いは別です。
実機では `ab` と `a`+`U+200B`+`b` が、`utf8mb4_0900_ai_ci`・`utf8mb4_0900_as_cs`・`utf8mb4_ja_0900_as_cs`・`utf8mb4_unicode_ci` のいずれでも `=` で同等になりました。
同じ組を `LIKE` で比較すると、完全一致・前方一致・部分一致のいずれも一致しません。
`a`+`U+200B`+`b` は `LIKE '___'` に一致するため、`LIKE` 側では3文字として数えられています。
UNIQUE制約では重複になるのに、`LIKE` 検索では見つからない値が生まれます。

異体字セレクターも同じ形です。
実機では `葛` と `葛`+`U+E0100` が、`utf8mb4_0900_ai_ci`・`utf8mb4_0900_as_cs`・`utf8mb4_ja_0900_as_cs` のいずれでも `=` で同等になり、`LIKE` では一致しませんでした。
`葛`+`U+E0100`+`飾` は `= '葛飾'` では見つかるのに、`LIKE '葛飾%'` では見つかりません。
日本語の氏名や地名では実際に入力される表現なので、原文と検索キーを分けるか、保存前の変換方針を決めます。

UTF-8では、画面上で1文字に見えるまとまりが、複数のコードポイントからできている場合があります。
例えば `ガ` は1コードポイントで3バイト、`ｶﾞ` は2コードポイントで6バイトです。
半角だから1バイトになるわけではありません。
入力欄の文字数制限、DBのカラム長、UNIQUE判定を同じ意味の制限として扱わないようにします。
`LENGTH()` と `CHAR_LENGTH()` の定義はMySQL公式の[String Functions and Operators](https://dev.mysql.com/doc/refman/8.4/en/string-functions.html)を参照します。

### UNIQUE制約と登録処理

UNIQUEは、インデックスに含めた値の重複を禁止します。
カラムやインデックスの定義によって、判定範囲が変わります。

* `UNIQUE (code)`：テーブル全体でコードの重複を禁止します。
* `UNIQUE (tenant_id, code)`：同じテナント内の重複を禁止します。両カラムを `NOT NULL` とする例では、別テナントに同じコードを登録できます。
* `UNIQUE (code(10))`：先頭10文字で判定します。11文字目以降が違っていても、先頭が同等なら重複です。

NULLを許可するカラムでは、UNIQUEがあっても複数のNULLを保存できます。
必須の識別子には `NOT NULL` も設定します。
ただし `NOT NULL` は空文字列を禁止しません。
必要なら入力検査やCHECK制約で禁止します。
文字列のPRIMARY KEYにも照合順序が関係し、既存行のキーを変更する `UPDATE` でも、他の行との重複は許可されません。
インデックスの重複判定と前方部分はMySQL公式の[CREATE INDEX](https://dev.mysql.com/doc/refman/8.4/en/create-index.html)と[PRIMARY KEY and UNIQUE Constraints](https://dev.mysql.com/doc/refman/8.4/en/constraint-primary-key.html)で確認できます。

照合順序による重複を、常にエラーとして受け取れるとは限りません。

| 登録方法 | 重複時の動作 | 設計上の注意 |
|---|---|---|
| 通常の `INSERT` | 重複エラー | アプリケーションでエラーを扱う |
| `INSERT IGNORE` | 登録せず警告 | 欠落を見逃さないようにする |
| `INSERT ... ON DUPLICATE KEY UPDATE` | 既存行を更新 | 同等と判定された別表記の行を更新し得る |

例えばコードが `ai_ci` のUNIQUEで、既に `ABC` があるとき、`abc` を重複時更新付きで送ると、`ABC` の既存行が更新対象になります。
別のコードのつもりで送ったデータを、既存行へ反映する危険があります。
動作の詳細はMySQL公式の[INSERT](https://dev.mysql.com/doc/refman/8.4/en/insert.html)と[INSERT ... ON DUPLICATE KEY UPDATE](https://dev.mysql.com/doc/refman/8.4/en/insert-on-duplicate.html)を参照します。

照合順序の変更では、登録件数だけでなく、取り込み処理や一括更新の重複時動作まで確認します。

### 検索式と並べ替え

等価比較で期待どおりでも、実際の検索、集計、並べ替えが同じ結果になるとは限りません。

| 処理 | 確認すること |
|---|---|
| `=` | 照合上の等価判定 |
| `LIKE` | 文字単位のパターン比較と末尾スペース |
| `DISTINCT` | 照合上同等な値の集約 |
| `GROUP BY` | 同等な値を同じグループにまとめる動作 |
| `ORDER BY` | 同じ重みの値に対する補助キー |
| `REGEXP_LIKE()` | `match_type` を含む正規表現の規則。照合順序から引き継ぐのは大文字小文字の区別だけ |
| `MATCH ... AGAINST` | パーサーとトークン化 |

`LIKE` は照合順序を参照するものの `=`・`DISTINCT`・`GROUP BY`・`ORDER BY` と同じ文字列全体の重み比較では動かない
以下ではまず `=` と `LIKE` の違いを確認し 正規表現と全文検索の処理規則はこの節の後半で扱う

`=` は文字列全体を重みの列に変換してから比較します。
`LIKE` はパターンを1コードポイントずつ対象と突き合わせます。
そのため、次のものが `=` と食い違います。

* ワイルドカードのない比較で両辺のコードポイント数が対応しない組 例えば `ß` と `ss`・`㈱` と `(株)`・合成済み文字と結合列
* コードポイント数が同じでも各位置の文字が一致しない組 例えば `ßs` と `sß`
* 重みを持たず照合上無視される文字。例えばゼロ幅スペース `U+200B` や異体字セレクター。
* `ks` が加えるひらがなとカタカナの区別。この区別は `=` と並べ替えに効き、`LIKE` の1文字比較には現れません。

展開の有無では判別できません。
`é` と `e`・`ば` と `は` も複数の照合要素に展開されるが `ai_ci` の文字比較では一次重みが一致するため `LIKE` でも一致する

文字列全体が照合上同等で コードポイント数も等しい場合でも `LIKE` の一致は保証されない
次のSQLをMySQL 8.4.11で実行した結果は `2`・`2`・`1`・`0` だった

```sql
SELECT
    CHAR_LENGTH(_utf8mb4'ßs') AS left_length,
    CHAR_LENGTH(_utf8mb4'sß') AS right_length,
    _utf8mb4'ßs' COLLATE utf8mb4_0900_ai_ci
        = _utf8mb4'sß' AS equal_result,
    _utf8mb4'ßs' COLLATE utf8mb4_0900_ai_ci
        LIKE _utf8mb4'sß' AS like_result;
```

[UCA 9.0の照合データ](https://www.unicode.org/Public/UCA/9.0.0/allkeys.txt)では `ß` の一次重みが `s` 二つに対応するため 文字列全体では両辺とも `sss` と同等になる
一方 `LIKE` が最初に比較するのは `ß` と `s` なので一致しない
ワイルドカードのないパターンでは 長さに加えて対応する各位置が `LIKE` の文字比較で一致する必要がある
これはMySQL公式の[文字単位のLIKE比較](https://dev.mysql.com/doc/refman/8.4/en/string-comparison-functions.html)の説明とも整合する

`ks` のかな区別が `LIKE` に現れないのは、MySQL 8.4.11の実装によるものです。
UCA 9.0.0の重みテーブルは[1照合要素あたり3重み](https://github.com/mysql/mysql-server/blob/99960bf74fa919347e4f4e3ca47672f333d6e91f/strings/uca900_data.h#L37)を持ち `utf8mb4_ja_0900_as_cs_ks` の [`levels_for_compare` は4](https://github.com/mysql/mysql-server/blob/99960bf74fa919347e4f4e3ca47672f333d6e91f/strings/ctype-uca.cc#L11263-L11296)に設定されている

かなの四次重みは走査時に [`uca_scanner_900::handle_ja_common_quat_wt()`](https://github.com/mysql/mysql-server/blob/99960bf74fa919347e4f4e3ca47672f333d6e91f/strings/ctype-uca.cc#L1436-L1473)が生成する

`LIKE` の文字比較は [`my_wildcmp_uca_impl()` から `my_uca_charcmp()` を経由](https://github.com/mysql/mysql-server/blob/99960bf74fa919347e4f4e3ca47672f333d6e91f/strings/ctype-uca.cc#L2212-L2280)し UCA 9.0では [`my_uca_charcmp_900()`](https://github.com/mysql/mysql-server/blob/99960bf74fa919347e4f4e3ca47672f333d6e91f/strings/ctype-uca.cc#L2113-L2177)で1コードポイントずつ比較する

この関数は重みテーブルを参照し 走査時のかなの四次重みを生成する処理を呼ばない

参照した `strings/ctype-uca.cc` と `strings/uca900_data.h` は [公式タグ `mysql-8.4.11`](https://github.com/mysql/mysql-server/tree/mysql-8.4.11)が指すコミット `99960bf74fa919347e4f4e3ca47672f333d6e91f` に固定している

この挙動は公式ドキュメントに記載がなく、将来のバージョンで変わり得ます。

実機で確認した代表例です。

| 組 | 照合順序 | `=` | `LIKE` | 理由 |
|---|---|---|---|---|
| `ガ` / `ｶﾞ` | `utf8mb4_0900_ai_ci` | 同等 | 一致しない | 1コードポイント対2コードポイント |
| `ß` / `ss` | `utf8mb4_0900_ai_ci` | 同等 | 一致しない | 1文字が2文字に展開される |
| `(株)` / `㈱` | `utf8mb4_0900_ai_ci` | 同等 | 一致しない | 3文字が1文字に対応する |
| `1` / `①` | `utf8mb4_0900_ai_ci` | 同等 | 一致する | 1文字同士の一次重みが一致する |
| `ab` / `a`+`U+200B`+`b` | `utf8mb4_0900_as_cs` | 同等 | 一致しない | `LIKE` は無視される文字も1文字と数える |
| `ABC` / `ABC ` | `utf8mb4_bin` | 同等 | 一致しない | `LIKE` はPAD属性を使わない |
| `かな` / `カナ` | `utf8mb4_ja_0900_as_cs_ks` | 異なる | 一致する | `ks` のかな区別が `LIKE` に伝わらない |
| `カナ` / `ｶﾅ` | `utf8mb4_0900_ai_ci` | 同等 | 一致する | 対応する各位置の一次重みが一致する |

この8行のうち、`=` で同等なのに `LIKE` で一致しないものが5行、逆に `=` で異なるのに `LIKE` で一致するものが1行あります。
残る2行は `=` と `LIKE` の結果が揃っています。
`LIKE` を `=` より狭いだけの判定として、一方向に覚えることはできません。
比較演算子の差はMySQL公式の[String Comparison Functions and Operators](https://dev.mysql.com/doc/refman/8.4/en/string-comparison-functions.html)で確認できます。

> [!WARNING] ワイルドカードのない `LIKE` を `=` の代用にしない
> `utf8mb4_ja_0900_as_cs_ks` のUNIQUE付きカラムに `かな` と `カナ` を登録し `WHERE v LIKE 'かな'` を実行したところ 索引を使った場合は `かな` だけが返った
>
> `IGNORE INDEX` を付けた場合は `かな` と `カナ` の両方が返った
>
> `EXPLAIN` では索引を使った側が `range` になり ワイルドカードのない `LIKE` が索引の範囲条件として `=` 相当に絞り込まれている
>
> 実行計画によって結果が変わる挙動には依存せず 等価比較と同じ結果を期待するなら `=` を使う
>
> これはMySQL 8.4.11で観測した挙動であり 公式ドキュメントに記載はない
>
> 索引の有無で結果が変わったのは `LIKE` が `=` より広く一致する組だけだった
>
> 同じカラムの `LIKE 'か%'` は索引の有無にかかわらず両方の行を返した
>
> `ガイドブック` / `ｶﾞｲﾄﾞﾌﾞｯｸ` や `(株)` / `㈱` のほか ゼロ幅スペースや `ß` / `ss` や `PAD SPACE` の末尾スペースのように `=` の方が広い組は 索引つきでも結果が同じだった
>
> これらの組は索引の範囲で広く拾ったあと `LIKE` で再度絞り込まれる

UNIQUE制約がなく、`Cafe` と `Café` の2行を保存できても、`ai_ci` で `DISTINCT name` を取ると同等の値がまとめられます。
`GROUP BY name` の集計も同じ比較規則の影響を受けます。

並べ替えで同じ重みになる値について、行の順番が一意に決まるとは限りません。
ページングなどで順番を安定させるなら、`ORDER BY name, id` のように一意なキーを補助条件にします。
同順位の順序はMySQL公式の[LIMIT Query Optimization](https://dev.mysql.com/doc/refman/8.4/en/limit-optimization.html)も参照します。

正規表現と全文検索にも、それぞれの処理規則があります。
実機の `REGEXP_LIKE()` では、`utf8mb4_0900_ai_ci` のとき `Cafe` が `^cafe$` に一致しました。
一方、同じ照合順序でも `café`・`ｶﾅ`・`かな` はそれぞれ `^cafe$`・`^カナ$` に一致しません。
`utf8mb4_0900_as_cs` にすると `Cafe` と `^cafe$` も一致しなくなります。
照合順序から正規表現へ引き継がれるのは大文字小文字の区別だけで、アクセント、幅、かなの同一視は伝わりません。
正規表現では[Regular Expressions](https://dev.mysql.com/doc/refman/8.4/en/regexp.html)、日本語の全文検索では[ngram Full-Text Parser](https://dev.mysql.com/doc/refman/8.4/en/fulltext-search-ngram.html)を確認します。
照合順序を変えるだけで、誤字の許容、同義語展開、読み仮名検索まで実現できるわけではありません。

## 実装と移行で確認すること

選んだ照合順序は、カラム定義だけでは評価できません。既存データ、索引、移行時のDDL、実際の検索条件まで含めて確かめます。
まず、日本語の商品名と、厳密に区別する商品コードを同じテーブルに持たせる例です。

```sql
CREATE TABLE products (
    id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
    name VARCHAR(255)
        CHARACTER SET utf8mb4
        COLLATE utf8mb4_ja_0900_as_cs NOT NULL,
    code VARCHAR(64)
        CHARACTER SET utf8mb4
        COLLATE utf8mb4_0900_bin NOT NULL,
    PRIMARY KEY (id),
    UNIQUE KEY uq_products_code (code)
) ENGINE = InnoDB
  DEFAULT CHARACTER SET utf8mb4
  COLLATE utf8mb4_0900_ai_ci;
```

この定義では、商品名の重複を許可し、商品コードの重複を禁止します。
`name` は英字の大文字小文字を区別するため、それを無視したい検索では、別の検索キーを設けるなど追加の方針が必要です。

`name` に選んだ `utf8mb4_ja_0900_as_cs` では、括弧や英数字の幅、`カナ` と `ｶﾅ` の同一視が `LIKE` でも効きます。
一方、`ガ` と `カ`+`U+3099` のような結合列は、`=` で同等でも `LIKE` では一致しません。
この結合列の差を持ち込まないために、登録時にNFC正規化を通した値だけを保存する前提で使います。
NFCで揃うのは正準等価な表現だけです。
半角濁点の `ｶﾞ`、ゼロ幅スペースなどの無視される文字、異体字セレクターは残ります。

保存、検索、一意判定で必要な処理が違うときは、原文と検索キー、一意判定キーを分けます。
ただし、キーの生成処理を登録、変更、検索の全経路で揃え、更新漏れを起こさない実装が必要です。
カラム単位の設定方法はMySQL公式の[Column Character Set and Collation](https://dev.mysql.com/doc/refman/8.4/en/charset-column.html)で確認できます。

### 既存のgeneral系とunicode系

既存DBで見かける照合順序には、次の違いがあります。

| 照合順序 | 文字セットと世代 | 保存できる範囲 | 代表的な比較 |
|---|---|---|---|
| `utf8mb3_general_ci` | `utf8mb3`の古いgeneral系 | 4バイトUTF-8文字を保存できない | `ß = s` |
| `utf8mb4_general_ci` | `utf8mb4`の簡易的なgeneral系 | 4バイトUTF-8文字も保存できる | `ß = s` |
| `utf8mb4_unicode_ci` | UCA 4.0 | 同上 | `ß = ss` |
| `utf8mb4_unicode_520_ci` | UCA 5.2 | 同上 | UCA 5.2に基づく |

`general_ci` と `unicode_ci` は、名前に `ai` がなくてもアクセントを区別しません。
両者の比較規則の差はUNIQUEにも影響し、`general_ci` なら `ß` と `s`、`unicode_ci` なら `ß` と `ss` を両方登録できません。

MySQL 8.4.11の `INFORMATION_SCHEMA.COLLATIONS` では、`utf8_general_ci` ではなく `utf8mb3_general_ci` と表示されます。
DDLの `CHARACTER SET utf8 COLLATE utf8_general_ci` は別名として受理されますが、`utf8mb3` とその照合順序が非推奨である警告が出ます。

結合文字の扱いにも差があります。
実機では、`utf8mb4_general_ci` が `ガ` と `カ`+`U+3099`、`é` と `e`+`U+0301` を区別し、`utf8mb4_unicode_ci` はそれぞれを同等に扱いました。
`general_ci` から `0900` 系へ変えると、合成済み文字と結合列の既存行が新たに衝突する場合があります。

日本語DBの移行では、`utf8mb4_general_ci` がかなと幅を区別する点の影響が最も大きくなります。

| 組 | `utf8mb4_general_ci` | `utf8mb4_unicode_ci` | `utf8mb4_0900_ai_ci` |
|---|---|---|---|
| `かな` / `カナ` | 異なる | 同等 | 同等 |
| `カナ` / `ｶﾅ` | 異なる | 同等 | 同等 |
| `は` / `ば` | 異なる | 同等 | 同等 |
| `つ` / `っ` | 異なる | 同等 | 同等 |
| `()` / `（）` | 異なる | 同等 | 同等 |
| `ABC123` / `ＡＢＣ１２３` | 異なる | 同等 | 同等 |

`general_ci` から移行すると、UNIQUEの衝突はまずこの6組で起きます。

さらに `utf8mb4_general_ci` と `utf8mb4_unicode_ci` は、補助平面の文字に同じ照合重みを割り当てます。
実機では単独の `😀` と `😁` が同等になり、UNIQUE付きでは両方登録できませんでした。
異なる平面どうしだから同等になるのではなく、補助平面の文字が互いに区別されません。
4バイト文字を保存できることと、比較で区別できることは別です。
ただし、これは世代ごとの性質です。
より新しい `utf8mb4_unicode_520_ci` では、同じ `😀` と `😁` が別の値になりました。
general系とunicode系をひとまとめにせず、使っている照合順序の名前で確認します。

`=` と `LIKE` の関係も世代によって違います。
`utf8mb4_general_ci` は1文字に1つの重みを割り当てるため、展開も無視される文字の扱いも持ちません。
`0900` 系で `=` と `LIKE` が割れた `ガ` / `ｶﾞ`、`ガ` / `カ`+`U+3099`、`ß` / `ss`、`(株)` / `㈱`、`1` / `①`、ゼロ幅スペースの組は、`general_ci` では `=` の時点で別の値になり、`LIKE` の結果もそれと揃いました。
大文字小文字とアクセントは `general_ci` でも同一視され、その組は `=` と `LIKE` の両方で一致します。
収録SQLで `general_ci` を確認した組のうち、`=` と `LIKE` が割れたのは末尾スペースの組だけです。
一方 `utf8mb4_unicode_ci` は `0900` 系と同じく、`ガ` / `ｶﾞ`・`ß` / `ss`・`(株)` / `㈱`・ゼロ幅スペースで `=` と `LIKE` が食い違います。
`general_ci` から `unicode_ci` や `0900` 系へ移行すると、既存の重複判定が変わるだけでなく、「UNIQUEでは重複、`LIKE` では見つからない」という組が新たに生まれます。
UCAの世代と旧照合順序の説明はMySQL公式の[Unicode Character Sets](https://dev.mysql.com/doc/refman/8.4/en/charset-unicode-sets.html)で確認できます。

古い世代からの変更では、文字範囲、比較結果、末尾スペースの扱いを個別に確認します。
新しい照合順序へ置き換えるだけで、既存の登録規則を維持できるとは限りません。

### 性能とインデックス

照合順序の名前だけで性能を決めず、実際のSQLとデータ量で測定します。
MySQL公式はUCA 9.0以降の照合順序の性能改善も説明していますが、アプリケーション固有の検索条件や索引構成は別に検証が必要です。

- [ ] 頻繁に使う検索式を `EXPLAIN` で確認する。
- [ ] `LIKE 'abc%'` と `LIKE '%abc%'` を分けて測る。
- [ ] 関数や別の照合順序を適用した式で索引の利用状況を確認する。
- [ ] 文字セット変更後の最大バイト数と複合索引全体の長さを確認する。
- [ ] 本番に近いデータ量で所要時間とロックの影響を測る。

検索時にカラムへ関数や別の照合順序を適用すると、既存インデックスで同じように絞り込めるとは限りません。
`COLLATE` を付ければ常にインデックスが使えなくなる、と断定するのも不正確です。
MySQLの[インデックス利用](https://dev.mysql.com/doc/refman/8.4/en/mysql-indexes.html)と[Range Optimization](https://dev.mysql.com/doc/refman/8.4/en/range-optimization.html)を踏まえ、`EXPLAIN` で確認します。

`LIKE '%abc%'` は先頭から文字が決まらないため、通常のB-treeインデックスで `LIKE 'abc%'` と同じ範囲検索はできません。

文字セットの変更では、最大バイト数に基づくキー長制限も確認します。
InnoDBの16KBページとDYNAMIC行形式では上限3072バイトが基準ですが、ページサイズや行形式で変わります。
すべての環境で `VARCHAR(191)` が必要というわけではありません。
複合インデックスなら他のカラムも含めて設計します。
上限の条件はMySQL公式の[InnoDB Limits](https://dev.mysql.com/doc/refman/8.4/en/innodb-limits.html)で確認できます。

### 既存DBの調査と移行

まず、バージョン、接続、実際のカラム定義を確認します。

```sql
SELECT VERSION(), @@version_comment;

SELECT
    @@character_set_server,
    @@collation_server,
    @@character_set_client,
    @@character_set_connection,
    @@character_set_results,
    @@collation_connection;

SELECT
    TABLE_NAME,
    COLUMN_NAME,
    COLUMN_TYPE,
    CHARACTER_SET_NAME,
    COLLATION_NAME,
    IS_NULLABLE
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = DATABASE()
  AND CHARACTER_SET_NAME IS NOT NULL
ORDER BY TABLE_NAME, ORDINAL_POSITION;

SELECT COLLATION_NAME, PAD_ATTRIBUTE
FROM INFORMATION_SCHEMA.COLLATIONS
WHERE CHARACTER_SET_NAME = 'utf8mb4'
ORDER BY COLLATION_NAME;

SHOW CREATE TABLE products;
SHOW INDEX FROM products;
```

DBのデフォルトを変更しても、既存カラムへ自動的には反映されません。
テーブルやカラムに個別指定があるため、DBの設定名だけでは調査を終えられません。

文字セットが既に `utf8mb4` の `products.code` を `utf8mb4_0900_ai_ci` に変える場合は、新しい比較規則で重複候補を調べます。

```sql
SELECT
    code COLLATE utf8mb4_0900_ai_ci AS proposed_key,
    COUNT(*) AS row_count,
    MIN(id) AS example_id
FROM products
WHERE code IS NOT NULL
GROUP BY code COLLATE utf8mb4_0900_ai_ci
HAVING COUNT(*) > 1;
```

これは単一カラム全体のUNIQUEを想定した確認です。
複合UNIQUEなら同じカラムの組み合わせ、前方部分のUNIQUEなら同じ長さ、アプリケーションで正規化するなら同じ変換後の値で確認します。

この `GROUP BY` は `=` と同じ規則で衝突を数えるだけなので、検索の回帰は別に確認します。
実際に使っている `LIKE` の条件を、移行前と移行後の照合順序で同じデータに対して実行し、返る件数と行を比べます。

`utf8mb3` のカラムに `utf8mb4` 用の `COLLATE` をそのまま指定することはできません。
その場合は、検証用コピーなどで `CONVERT(code USING utf8mb4) COLLATE utf8mb4_0900_ai_ci` のように、移行後と一致した式を使います。

新しい衝突だけでなく、従来は同一だった値が別々になる変化も調べます。
`PAD SPACE` から `NO PAD` へ変えると、これまで拒否していた `ABC ` を登録できるようになります。
既存データにその値がなければ、重複検出SQLだけでは見つかりません。

移行では次の順序を確認します。

1. 用途ごとに変更対象のカラムを特定する。
2. 移行後と同じ比較式で衝突候補と分離される値を調べる。この確認は `=` の話なので、主要な `LIKE` 検索条件も移行前後の照合順序で実行し、件数を比べる。
3. 外部キーとJOIN対象の文字セットと照合順序を確認する。
4. 書き込み停止または移行中の同一規則を決める。
5. 検証環境でDDL、索引再構築、ロック、所要時間を測る。
6. バックアップだけでなく復元手順を確認する。

5番目は、照合順序の議論から外れて見えて軽視しやすい項目です。
長時間のDDLが後続クエリを止める待機の連鎖については、[PostgreSQLで実際に起きた事例](/blog/postgresql-csv-ddl-lock-chain)を別記事にまとめています。
製品は異なりますが、所要時間とロックの影響を移行前に見積もる観点は共通です。

`ALTER TABLE ... CONVERT TO CHARACTER SET ... COLLATE ...` は、テーブルのデフォルトと文字列カラム全体を変更します。
商品コード用の `bin` 指定まで置き換える可能性があるため、用途別に設定したテーブルへ一律適用しないようにします。
実機では、`bin`・`general_ci`・`ja_0900_as_cs` が混在する3カラムを一括変換すると、3カラムすべてが指定した `utf8mb4_0900_ai_ci` になりました。
変更後の照合順序でUNIQUE衝突が残る場合は、`ALTER TABLE` がエラー1062で失敗し、元の照合順序が維持されます。

個別変更には `MODIFY` などを使いますが、型、NULL許可、デフォルト値などを含め、保持すべき定義を明示します。
実機では、`MODIFY` から属性を省いた結果、`NOT NULL` がNULL許可へ変わり、デフォルト値とコメントも失われました。
文字セット変換では `TEXT` から `MEDIUMTEXT` など、型が自動変更される場合もあります。
テーブル全体とカラム単位の変換差はMySQL公式の[ALTER TABLE](https://dev.mysql.com/doc/refman/8.4/en/alter-table.html)と[Column Character Set Conversion](https://dev.mysql.com/doc/refman/8.4/en/charset-conversion.html)を参照します。

文字列の外部キーと参照先には、同じ文字セットと照合順序が必要です。
通常のJOINでも、同じ意味のキー同士は揃えます。
照合順序が混在した比較は、優先順位に従って処理されたり、`Illegal mix of collations` エラーになったりします。
比較時の優先順位は[Collation Coercibility](https://dev.mysql.com/doc/refman/8.4/en/charset-collation-coercibility.html)、外部キーの要件は[FOREIGN KEY Constraints](https://dev.mysql.com/doc/refman/8.4/en/create-table-foreign-keys.html)で確認できます。

MySQL 5.7には `0900` 系がありません。
MariaDBや他のMySQL互換DBへの移行も、製品名とバージョンを確認し、MySQL 8.4の説明をそのまま適用しないようにします。

### 比較結果を実機で確かめる

比較には文字セットと照合順序を明示し、接続設定に任せたリテラル比較を避けます。
記事の35セルと追加例を一括確認する比較SQL、各組を空の一時テーブルで確認するUNIQUE確認SQL、`=` と `LIKE` の差を確認するLIKE確認SQLを、以下に全文収録しました。必要なものだけ展開し、そのまま全文をコピーできます。

### 比較SQL

本文の比較表35セルと追加例を一括で再確認するSQLです。

```sql
-- MySQL 8.4 collation comparison verification for the EastBraver Labs article.
-- Run with a client configured for utf8mb4 and preserve the output as evidence.
-- This standalone SQL reports mismatches but does not make the client exit nonzero.
-- Use apps/web/scripts/verify-mysql-collation.mjs for a strict automated gate.

SET NAMES utf8mb4 COLLATE utf8mb4_0900_ai_ci;

SELECT
    VERSION() AS mysql_version,
    @@version_comment AS version_comment,
    @@sql_mode AS sql_mode,
    @@character_set_client AS character_set_client,
    @@character_set_connection AS character_set_connection,
    @@character_set_results AS character_set_results,
    @@collation_connection AS collation_connection;

DROP TEMPORARY TABLE IF EXISTS comparison_results;

CREATE TEMPORARY TABLE comparison_results (
    scope_name VARCHAR(16) CHARACTER SET ascii NOT NULL,
    collation_name VARCHAR(64) CHARACTER SET ascii NOT NULL,
    pair_name VARCHAR(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_bin NOT NULL,
    left_value VARCHAR(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_bin NOT NULL,
    right_value VARCHAR(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_bin NOT NULL,
    expected_equal TINYINT UNSIGNED NOT NULL,
    actual_equal TINYINT UNSIGNED NOT NULL,
    left_hex VARCHAR(256) CHARACTER SET ascii NOT NULL,
    right_hex VARCHAR(256) CHARACTER SET ascii NOT NULL
);

-- The 35 cells in the article's main comparison matrix.
INSERT INTO comparison_results VALUES
    ('matrix', 'utf8mb4_0900_ai_ci', 'case', _utf8mb4'Cafe', _utf8mb4'cafe', 1, _utf8mb4'Cafe' COLLATE utf8mb4_0900_ai_ci = _utf8mb4'cafe', HEX(_utf8mb4'Cafe'), HEX(_utf8mb4'cafe')),
    ('matrix', 'utf8mb4_0900_ai_ci', 'accent', _utf8mb4'cafe', _utf8mb4'café', 1, _utf8mb4'cafe' COLLATE utf8mb4_0900_ai_ci = _utf8mb4'café', HEX(_utf8mb4'cafe'), HEX(_utf8mb4'café')),
    ('matrix', 'utf8mb4_0900_ai_ci', 'width-parentheses', _utf8mb4'()', _utf8mb4'（）', 1, _utf8mb4'()' COLLATE utf8mb4_0900_ai_ci = _utf8mb4'（）', HEX(_utf8mb4'()'), HEX(_utf8mb4'（）')),
    ('matrix', 'utf8mb4_0900_ai_ci', 'hiragana-katakana', _utf8mb4'かな', _utf8mb4'カナ', 1, _utf8mb4'かな' COLLATE utf8mb4_0900_ai_ci = _utf8mb4'カナ', HEX(_utf8mb4'かな'), HEX(_utf8mb4'カナ')),
    ('matrix', 'utf8mb4_0900_ai_ci', 'katakana-width', _utf8mb4'カナ', _utf8mb4'ｶﾅ', 1, _utf8mb4'カナ' COLLATE utf8mb4_0900_ai_ci = _utf8mb4'ｶﾅ', HEX(_utf8mb4'カナ'), HEX(_utf8mb4'ｶﾅ')),
    ('matrix', 'utf8mb4_0900_ai_ci', 'voicing', _utf8mb4'は', _utf8mb4'ば', 1, _utf8mb4'は' COLLATE utf8mb4_0900_ai_ci = _utf8mb4'ば', HEX(_utf8mb4'は'), HEX(_utf8mb4'ば')),
    ('matrix', 'utf8mb4_0900_ai_ci', 'small-kana', _utf8mb4'つ', _utf8mb4'っ', 1, _utf8mb4'つ' COLLATE utf8mb4_0900_ai_ci = _utf8mb4'っ', HEX(_utf8mb4'つ'), HEX(_utf8mb4'っ')),
    ('matrix', 'utf8mb4_0900_as_ci', 'case', _utf8mb4'Cafe', _utf8mb4'cafe', 1, _utf8mb4'Cafe' COLLATE utf8mb4_0900_as_ci = _utf8mb4'cafe', HEX(_utf8mb4'Cafe'), HEX(_utf8mb4'cafe')),
    ('matrix', 'utf8mb4_0900_as_ci', 'accent', _utf8mb4'cafe', _utf8mb4'café', 0, _utf8mb4'cafe' COLLATE utf8mb4_0900_as_ci = _utf8mb4'café', HEX(_utf8mb4'cafe'), HEX(_utf8mb4'café')),
    ('matrix', 'utf8mb4_0900_as_ci', 'width-parentheses', _utf8mb4'()', _utf8mb4'（）', 1, _utf8mb4'()' COLLATE utf8mb4_0900_as_ci = _utf8mb4'（）', HEX(_utf8mb4'()'), HEX(_utf8mb4'（）')),
    ('matrix', 'utf8mb4_0900_as_ci', 'hiragana-katakana', _utf8mb4'かな', _utf8mb4'カナ', 1, _utf8mb4'かな' COLLATE utf8mb4_0900_as_ci = _utf8mb4'カナ', HEX(_utf8mb4'かな'), HEX(_utf8mb4'カナ')),
    ('matrix', 'utf8mb4_0900_as_ci', 'katakana-width', _utf8mb4'カナ', _utf8mb4'ｶﾅ', 1, _utf8mb4'カナ' COLLATE utf8mb4_0900_as_ci = _utf8mb4'ｶﾅ', HEX(_utf8mb4'カナ'), HEX(_utf8mb4'ｶﾅ')),
    ('matrix', 'utf8mb4_0900_as_ci', 'voicing', _utf8mb4'は', _utf8mb4'ば', 0, _utf8mb4'は' COLLATE utf8mb4_0900_as_ci = _utf8mb4'ば', HEX(_utf8mb4'は'), HEX(_utf8mb4'ば')),
    ('matrix', 'utf8mb4_0900_as_ci', 'small-kana', _utf8mb4'つ', _utf8mb4'っ', 1, _utf8mb4'つ' COLLATE utf8mb4_0900_as_ci = _utf8mb4'っ', HEX(_utf8mb4'つ'), HEX(_utf8mb4'っ')),
    ('matrix', 'utf8mb4_0900_as_cs', 'case', _utf8mb4'Cafe', _utf8mb4'cafe', 0, _utf8mb4'Cafe' COLLATE utf8mb4_0900_as_cs = _utf8mb4'cafe', HEX(_utf8mb4'Cafe'), HEX(_utf8mb4'cafe')),
    ('matrix', 'utf8mb4_0900_as_cs', 'accent', _utf8mb4'cafe', _utf8mb4'café', 0, _utf8mb4'cafe' COLLATE utf8mb4_0900_as_cs = _utf8mb4'café', HEX(_utf8mb4'cafe'), HEX(_utf8mb4'café')),
    ('matrix', 'utf8mb4_0900_as_cs', 'width-parentheses', _utf8mb4'()', _utf8mb4'（）', 0, _utf8mb4'()' COLLATE utf8mb4_0900_as_cs = _utf8mb4'（）', HEX(_utf8mb4'()'), HEX(_utf8mb4'（）')),
    ('matrix', 'utf8mb4_0900_as_cs', 'hiragana-katakana', _utf8mb4'かな', _utf8mb4'カナ', 0, _utf8mb4'かな' COLLATE utf8mb4_0900_as_cs = _utf8mb4'カナ', HEX(_utf8mb4'かな'), HEX(_utf8mb4'カナ')),
    ('matrix', 'utf8mb4_0900_as_cs', 'katakana-width', _utf8mb4'カナ', _utf8mb4'ｶﾅ', 0, _utf8mb4'カナ' COLLATE utf8mb4_0900_as_cs = _utf8mb4'ｶﾅ', HEX(_utf8mb4'カナ'), HEX(_utf8mb4'ｶﾅ')),
    ('matrix', 'utf8mb4_0900_as_cs', 'voicing', _utf8mb4'は', _utf8mb4'ば', 0, _utf8mb4'は' COLLATE utf8mb4_0900_as_cs = _utf8mb4'ば', HEX(_utf8mb4'は'), HEX(_utf8mb4'ば')),
    ('matrix', 'utf8mb4_0900_as_cs', 'small-kana', _utf8mb4'つ', _utf8mb4'っ', 0, _utf8mb4'つ' COLLATE utf8mb4_0900_as_cs = _utf8mb4'っ', HEX(_utf8mb4'つ'), HEX(_utf8mb4'っ')),
    ('matrix', 'utf8mb4_ja_0900_as_cs', 'case', _utf8mb4'Cafe', _utf8mb4'cafe', 0, _utf8mb4'Cafe' COLLATE utf8mb4_ja_0900_as_cs = _utf8mb4'cafe', HEX(_utf8mb4'Cafe'), HEX(_utf8mb4'cafe')),
    ('matrix', 'utf8mb4_ja_0900_as_cs', 'accent', _utf8mb4'cafe', _utf8mb4'café', 0, _utf8mb4'cafe' COLLATE utf8mb4_ja_0900_as_cs = _utf8mb4'café', HEX(_utf8mb4'cafe'), HEX(_utf8mb4'café')),
    ('matrix', 'utf8mb4_ja_0900_as_cs', 'width-parentheses', _utf8mb4'()', _utf8mb4'（）', 1, _utf8mb4'()' COLLATE utf8mb4_ja_0900_as_cs = _utf8mb4'（）', HEX(_utf8mb4'()'), HEX(_utf8mb4'（）')),
    ('matrix', 'utf8mb4_ja_0900_as_cs', 'hiragana-katakana', _utf8mb4'かな', _utf8mb4'カナ', 1, _utf8mb4'かな' COLLATE utf8mb4_ja_0900_as_cs = _utf8mb4'カナ', HEX(_utf8mb4'かな'), HEX(_utf8mb4'カナ')),
    ('matrix', 'utf8mb4_ja_0900_as_cs', 'katakana-width', _utf8mb4'カナ', _utf8mb4'ｶﾅ', 1, _utf8mb4'カナ' COLLATE utf8mb4_ja_0900_as_cs = _utf8mb4'ｶﾅ', HEX(_utf8mb4'カナ'), HEX(_utf8mb4'ｶﾅ')),
    ('matrix', 'utf8mb4_ja_0900_as_cs', 'voicing', _utf8mb4'は', _utf8mb4'ば', 0, _utf8mb4'は' COLLATE utf8mb4_ja_0900_as_cs = _utf8mb4'ば', HEX(_utf8mb4'は'), HEX(_utf8mb4'ば')),
    ('matrix', 'utf8mb4_ja_0900_as_cs', 'small-kana', _utf8mb4'つ', _utf8mb4'っ', 0, _utf8mb4'つ' COLLATE utf8mb4_ja_0900_as_cs = _utf8mb4'っ', HEX(_utf8mb4'つ'), HEX(_utf8mb4'っ')),
    ('matrix', 'utf8mb4_ja_0900_as_cs_ks', 'case', _utf8mb4'Cafe', _utf8mb4'cafe', 0, _utf8mb4'Cafe' COLLATE utf8mb4_ja_0900_as_cs_ks = _utf8mb4'cafe', HEX(_utf8mb4'Cafe'), HEX(_utf8mb4'cafe')),
    ('matrix', 'utf8mb4_ja_0900_as_cs_ks', 'accent', _utf8mb4'cafe', _utf8mb4'café', 0, _utf8mb4'cafe' COLLATE utf8mb4_ja_0900_as_cs_ks = _utf8mb4'café', HEX(_utf8mb4'cafe'), HEX(_utf8mb4'café')),
    ('matrix', 'utf8mb4_ja_0900_as_cs_ks', 'width-parentheses', _utf8mb4'()', _utf8mb4'（）', 1, _utf8mb4'()' COLLATE utf8mb4_ja_0900_as_cs_ks = _utf8mb4'（）', HEX(_utf8mb4'()'), HEX(_utf8mb4'（）')),
    ('matrix', 'utf8mb4_ja_0900_as_cs_ks', 'hiragana-katakana', _utf8mb4'かな', _utf8mb4'カナ', 0, _utf8mb4'かな' COLLATE utf8mb4_ja_0900_as_cs_ks = _utf8mb4'カナ', HEX(_utf8mb4'かな'), HEX(_utf8mb4'カナ')),
    ('matrix', 'utf8mb4_ja_0900_as_cs_ks', 'katakana-width', _utf8mb4'カナ', _utf8mb4'ｶﾅ', 1, _utf8mb4'カナ' COLLATE utf8mb4_ja_0900_as_cs_ks = _utf8mb4'ｶﾅ', HEX(_utf8mb4'カナ'), HEX(_utf8mb4'ｶﾅ')),
    ('matrix', 'utf8mb4_ja_0900_as_cs_ks', 'voicing', _utf8mb4'は', _utf8mb4'ば', 0, _utf8mb4'は' COLLATE utf8mb4_ja_0900_as_cs_ks = _utf8mb4'ば', HEX(_utf8mb4'は'), HEX(_utf8mb4'ば')),
    ('matrix', 'utf8mb4_ja_0900_as_cs_ks', 'small-kana', _utf8mb4'つ', _utf8mb4'っ', 0, _utf8mb4'つ' COLLATE utf8mb4_ja_0900_as_cs_ks = _utf8mb4'っ', HEX(_utf8mb4'つ'), HEX(_utf8mb4'っ'));

-- Additional claims discussed in the article.
INSERT INTO comparison_results VALUES
    ('additional', 'utf8mb4_0900_ai_ci', 'voiced-katakana-width', _utf8mb4'ガ', _utf8mb4'ｶﾞ', 1, _utf8mb4'ガ' COLLATE utf8mb4_0900_ai_ci = _utf8mb4'ｶﾞ', HEX(_utf8mb4'ガ'), HEX(_utf8mb4'ｶﾞ')),
    ('additional', 'utf8mb4_0900_as_ci', 'voiced-katakana-width', _utf8mb4'ガ', _utf8mb4'ｶﾞ', 1, _utf8mb4'ガ' COLLATE utf8mb4_0900_as_ci = _utf8mb4'ｶﾞ', HEX(_utf8mb4'ガ'), HEX(_utf8mb4'ｶﾞ')),
    ('additional', 'utf8mb4_0900_as_cs', 'voiced-katakana-width', _utf8mb4'ガ', _utf8mb4'ｶﾞ', 0, _utf8mb4'ガ' COLLATE utf8mb4_0900_as_cs = _utf8mb4'ｶﾞ', HEX(_utf8mb4'ガ'), HEX(_utf8mb4'ｶﾞ')),
    ('additional', 'utf8mb4_ja_0900_as_cs', 'voiced-katakana-width', _utf8mb4'ガ', _utf8mb4'ｶﾞ', 0, _utf8mb4'ガ' COLLATE utf8mb4_ja_0900_as_cs = _utf8mb4'ｶﾞ', HEX(_utf8mb4'ガ'), HEX(_utf8mb4'ｶﾞ')),
    ('additional', 'utf8mb4_ja_0900_as_cs_ks', 'voiced-katakana-width', _utf8mb4'ガ', _utf8mb4'ｶﾞ', 0, _utf8mb4'ガ' COLLATE utf8mb4_ja_0900_as_cs_ks = _utf8mb4'ｶﾞ', HEX(_utf8mb4'ガ'), HEX(_utf8mb4'ｶﾞ')),
    ('additional', 'utf8mb4_0900_as_cs', 'canonical-equivalent-katakana', _utf8mb4'ガ', CONVERT(0xE382ABE38299 USING utf8mb4), 1, _utf8mb4'ガ' COLLATE utf8mb4_0900_as_cs = CONVERT(0xE382ABE38299 USING utf8mb4), HEX(_utf8mb4'ガ'), HEX(CONVERT(0xE382ABE38299 USING utf8mb4))),
    ('additional', 'utf8mb4_ja_0900_as_cs', 'canonical-equivalent-katakana', _utf8mb4'ガ', CONVERT(0xE382ABE38299 USING utf8mb4), 1, _utf8mb4'ガ' COLLATE utf8mb4_ja_0900_as_cs = CONVERT(0xE382ABE38299 USING utf8mb4), HEX(_utf8mb4'ガ'), HEX(CONVERT(0xE382ABE38299 USING utf8mb4))),
    ('additional', 'utf8mb4_0900_bin', 'canonical-equivalent-katakana', _utf8mb4'ガ', CONVERT(0xE382ABE38299 USING utf8mb4), 0, _utf8mb4'ガ' COLLATE utf8mb4_0900_bin = CONVERT(0xE382ABE38299 USING utf8mb4), HEX(_utf8mb4'ガ'), HEX(CONVERT(0xE382ABE38299 USING utf8mb4))),
    ('additional', 'utf8mb4_0900_as_cs', 'zero-width-space', _utf8mb4'A', CONVERT(0x41E2808B USING utf8mb4), 1, _utf8mb4'A' COLLATE utf8mb4_0900_as_cs = CONVERT(0x41E2808B USING utf8mb4), HEX(_utf8mb4'A'), HEX(CONVERT(0x41E2808B USING utf8mb4))),
    ('additional', 'utf8mb4_0900_bin', 'zero-width-space', _utf8mb4'A', CONVERT(0x41E2808B USING utf8mb4), 0, _utf8mb4'A' COLLATE utf8mb4_0900_bin = CONVERT(0x41E2808B USING utf8mb4), HEX(_utf8mb4'A'), HEX(CONVERT(0x41E2808B USING utf8mb4))),
    ('additional', 'utf8mb4_bin', 'trailing-space', _utf8mb4'ABC', _utf8mb4'ABC ', 1, _utf8mb4'ABC' COLLATE utf8mb4_bin = _utf8mb4'ABC ', HEX(_utf8mb4'ABC'), HEX(_utf8mb4'ABC ')),
    ('additional', 'utf8mb4_0900_bin', 'trailing-space', _utf8mb4'ABC', _utf8mb4'ABC ', 0, _utf8mb4'ABC' COLLATE utf8mb4_0900_bin = _utf8mb4'ABC ', HEX(_utf8mb4'ABC'), HEX(_utf8mb4'ABC ')),
    ('additional', 'utf8mb4_ja_0900_as_cs', 'space-width', _utf8mb4' ', _utf8mb4'　', 1, _utf8mb4' ' COLLATE utf8mb4_ja_0900_as_cs = _utf8mb4'　', HEX(_utf8mb4' '), HEX(_utf8mb4'　')),
    ('additional', 'utf8mb4_general_ci', 'supplementary-plane', _utf8mb4'😀', _utf8mb4'😁', 1, _utf8mb4'😀' COLLATE utf8mb4_general_ci = _utf8mb4'😁', HEX(_utf8mb4'😀'), HEX(_utf8mb4'😁')),
    ('additional', 'utf8mb4_unicode_ci', 'supplementary-plane', _utf8mb4'😀', _utf8mb4'😁', 1, _utf8mb4'😀' COLLATE utf8mb4_unicode_ci = _utf8mb4'😁', HEX(_utf8mb4'😀'), HEX(_utf8mb4'😁')),
    ('additional', 'utf8mb4_general_ci', 'sharp-s', _utf8mb4'ß', _utf8mb4's', 1, _utf8mb4'ß' COLLATE utf8mb4_general_ci = _utf8mb4's', HEX(_utf8mb4'ß'), HEX(_utf8mb4's')),
    ('additional', 'utf8mb4_unicode_ci', 'sharp-s-expansion', _utf8mb4'ß', _utf8mb4'ss', 1, _utf8mb4'ß' COLLATE utf8mb4_unicode_ci = _utf8mb4'ss', HEX(_utf8mb4'ß'), HEX(_utf8mb4'ss')),
    ('additional', 'utf8mb4_0900_ai_ci', 'hex-alnum-width', _utf8mb4'ab12', _utf8mb4'ＡＢ１２', 1, _utf8mb4'ab12' COLLATE utf8mb4_0900_ai_ci = _utf8mb4'ＡＢ１２', HEX(_utf8mb4'ab12'), HEX(_utf8mb4'ＡＢ１２')),
    ('additional', 'utf8mb4_0900_bin', 'hex-alnum-width', _utf8mb4'ab12', _utf8mb4'ＡＢ１２', 0, _utf8mb4'ab12' COLLATE utf8mb4_0900_bin = _utf8mb4'ＡＢ１２', HEX(_utf8mb4'ab12'), HEX(_utf8mb4'ＡＢ１２')),
    ('additional', 'utf8mb4_0900_ai_ci', 'hex-zero-width-space', _utf8mb4'deadbeef', CONVERT(0x64656164E2808B62656566 USING utf8mb4), 1, _utf8mb4'deadbeef' COLLATE utf8mb4_0900_ai_ci = CONVERT(0x64656164E2808B62656566 USING utf8mb4), HEX(_utf8mb4'deadbeef'), HEX(CONVERT(0x64656164E2808B62656566 USING utf8mb4))),
    ('additional', 'utf8mb4_0900_bin', 'hex-zero-width-space', _utf8mb4'deadbeef', CONVERT(0x64656164E2808B62656566 USING utf8mb4), 0, _utf8mb4'deadbeef' COLLATE utf8mb4_0900_bin = CONVERT(0x64656164E2808B62656566 USING utf8mb4), HEX(_utf8mb4'deadbeef'), HEX(CONVERT(0x64656164E2808B62656566 USING utf8mb4))),
    ('additional', 'utf8mb4_0900_ai_ci', 'variation-selector', _utf8mb4'葛', CONVERT(0xE8919BF3A08480 USING utf8mb4), 1, _utf8mb4'葛' COLLATE utf8mb4_0900_ai_ci = CONVERT(0xE8919BF3A08480 USING utf8mb4), HEX(_utf8mb4'葛'), HEX(CONVERT(0xE8919BF3A08480 USING utf8mb4))),
    ('additional', 'utf8mb4_0900_as_cs', 'variation-selector', _utf8mb4'葛', CONVERT(0xE8919BF3A08480 USING utf8mb4), 1, _utf8mb4'葛' COLLATE utf8mb4_0900_as_cs = CONVERT(0xE8919BF3A08480 USING utf8mb4), HEX(_utf8mb4'葛'), HEX(CONVERT(0xE8919BF3A08480 USING utf8mb4))),
    ('additional', 'utf8mb4_ja_0900_as_cs', 'variation-selector', _utf8mb4'葛', CONVERT(0xE8919BF3A08480 USING utf8mb4), 1, _utf8mb4'葛' COLLATE utf8mb4_ja_0900_as_cs = CONVERT(0xE8919BF3A08480 USING utf8mb4), HEX(_utf8mb4'葛'), HEX(CONVERT(0xE8919BF3A08480 USING utf8mb4))),
    ('additional', 'utf8mb4_0900_bin', 'variation-selector', _utf8mb4'葛', CONVERT(0xE8919BF3A08480 USING utf8mb4), 0, _utf8mb4'葛' COLLATE utf8mb4_0900_bin = CONVERT(0xE8919BF3A08480 USING utf8mb4), HEX(_utf8mb4'葛'), HEX(CONVERT(0xE8919BF3A08480 USING utf8mb4))),
    ('additional', 'utf8mb4_general_ci', 'hiragana-katakana', _utf8mb4'かな', _utf8mb4'カナ', 0, _utf8mb4'かな' COLLATE utf8mb4_general_ci = _utf8mb4'カナ', HEX(_utf8mb4'かな'), HEX(_utf8mb4'カナ')),
    ('additional', 'utf8mb4_unicode_ci', 'hiragana-katakana', _utf8mb4'かな', _utf8mb4'カナ', 1, _utf8mb4'かな' COLLATE utf8mb4_unicode_ci = _utf8mb4'カナ', HEX(_utf8mb4'かな'), HEX(_utf8mb4'カナ')),
    ('additional', 'utf8mb4_general_ci', 'katakana-width', _utf8mb4'カナ', _utf8mb4'ｶﾅ', 0, _utf8mb4'カナ' COLLATE utf8mb4_general_ci = _utf8mb4'ｶﾅ', HEX(_utf8mb4'カナ'), HEX(_utf8mb4'ｶﾅ')),
    ('additional', 'utf8mb4_unicode_ci', 'katakana-width', _utf8mb4'カナ', _utf8mb4'ｶﾅ', 1, _utf8mb4'カナ' COLLATE utf8mb4_unicode_ci = _utf8mb4'ｶﾅ', HEX(_utf8mb4'カナ'), HEX(_utf8mb4'ｶﾅ')),
    ('additional', 'utf8mb4_general_ci', 'voicing', _utf8mb4'は', _utf8mb4'ば', 0, _utf8mb4'は' COLLATE utf8mb4_general_ci = _utf8mb4'ば', HEX(_utf8mb4'は'), HEX(_utf8mb4'ば')),
    ('additional', 'utf8mb4_unicode_ci', 'voicing', _utf8mb4'は', _utf8mb4'ば', 1, _utf8mb4'は' COLLATE utf8mb4_unicode_ci = _utf8mb4'ば', HEX(_utf8mb4'は'), HEX(_utf8mb4'ば')),
    ('additional', 'utf8mb4_general_ci', 'small-kana', _utf8mb4'つ', _utf8mb4'っ', 0, _utf8mb4'つ' COLLATE utf8mb4_general_ci = _utf8mb4'っ', HEX(_utf8mb4'つ'), HEX(_utf8mb4'っ')),
    ('additional', 'utf8mb4_unicode_ci', 'small-kana', _utf8mb4'つ', _utf8mb4'っ', 1, _utf8mb4'つ' COLLATE utf8mb4_unicode_ci = _utf8mb4'っ', HEX(_utf8mb4'つ'), HEX(_utf8mb4'っ')),
    ('additional', 'utf8mb4_general_ci', 'width-parentheses', _utf8mb4'()', _utf8mb4'（）', 0, _utf8mb4'()' COLLATE utf8mb4_general_ci = _utf8mb4'（）', HEX(_utf8mb4'()'), HEX(_utf8mb4'（）')),
    ('additional', 'utf8mb4_unicode_ci', 'width-parentheses', _utf8mb4'()', _utf8mb4'（）', 1, _utf8mb4'()' COLLATE utf8mb4_unicode_ci = _utf8mb4'（）', HEX(_utf8mb4'()'), HEX(_utf8mb4'（）')),
    ('additional', 'utf8mb4_general_ci', 'alnum-width', _utf8mb4'ABC123', _utf8mb4'ＡＢＣ１２３', 0, _utf8mb4'ABC123' COLLATE utf8mb4_general_ci = _utf8mb4'ＡＢＣ１２３', HEX(_utf8mb4'ABC123'), HEX(_utf8mb4'ＡＢＣ１２３')),
    ('additional', 'utf8mb4_unicode_ci', 'alnum-width', _utf8mb4'ABC123', _utf8mb4'ＡＢＣ１２３', 1, _utf8mb4'ABC123' COLLATE utf8mb4_unicode_ci = _utf8mb4'ＡＢＣ１２３', HEX(_utf8mb4'ABC123'), HEX(_utf8mb4'ＡＢＣ１２３'));

SELECT
    COUNT(*) AS matrix_cells,
    SUM(actual_equal <> expected_equal) AS matrix_mismatches
FROM comparison_results
WHERE scope_name = 'matrix';

SELECT
    COUNT(*) AS additional_checks,
    SUM(actual_equal <> expected_equal) AS additional_mismatches
FROM comparison_results
WHERE scope_name = 'additional';

SELECT *
FROM comparison_results
WHERE actual_equal <> expected_equal
ORDER BY scope_name, collation_name, pair_name;

SELECT
    scope_name,
    collation_name,
    pair_name,
    expected_equal,
    actual_equal,
    left_hex,
    right_hex
FROM comparison_results
ORDER BY scope_name, collation_name, pair_name;
```
### UNIQUE確認SQL

各組を空の一時テーブルへ通常INSERTし、重複判定と保存HEXを確認するSQLです。

```sql
-- MySQL 8.4 UNIQUE verification for the EastBraver Labs article.
-- Each pair uses a newly created table so no previous row affects the result.
-- Run only in a dedicated database because this file drops and creates
-- the non-temporary stored procedure run_unique_verification.
-- This standalone SQL reports mismatches but does not make the client exit nonzero.
-- Use apps/web/scripts/verify-mysql-collation.mjs for a strict automated gate.

SET NAMES utf8mb4 COLLATE utf8mb4_0900_ai_ci;

SELECT
    VERSION() AS mysql_version,
    @@version_comment AS version_comment,
    @@sql_mode AS sql_mode,
    @@character_set_client AS character_set_client,
    @@character_set_connection AS character_set_connection,
    @@character_set_results AS character_set_results,
    @@collation_connection AS collation_connection;

DROP TEMPORARY TABLE IF EXISTS unique_test_cases;
DROP TEMPORARY TABLE IF EXISTS unique_results;
DROP TEMPORARY TABLE IF EXISTS matrix_collations;
DROP TEMPORARY TABLE IF EXISTS matrix_pairs;

CREATE TEMPORARY TABLE unique_test_cases (
    case_order INT UNSIGNED NOT NULL AUTO_INCREMENT,
    scope_name VARCHAR(16) CHARACTER SET ascii NOT NULL,
    collation_name VARCHAR(64) CHARACTER SET ascii NOT NULL,
    pair_name VARCHAR(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_bin NOT NULL,
    left_value VARCHAR(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_bin NOT NULL,
    right_value VARCHAR(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_bin NOT NULL,
    expected_duplicate TINYINT UNSIGNED NOT NULL,
    PRIMARY KEY (case_order)
);

CREATE TEMPORARY TABLE unique_results (
    case_order INT UNSIGNED NOT NULL,
    scope_name VARCHAR(16) CHARACTER SET ascii NOT NULL,
    collation_name VARCHAR(64) CHARACTER SET ascii NOT NULL,
    pair_name VARCHAR(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_bin NOT NULL,
    expected_duplicate TINYINT UNSIGNED NOT NULL,
    actual_duplicate TINYINT UNSIGNED NOT NULL,
    left_input_hex VARCHAR(256) CHARACTER SET ascii NOT NULL,
    right_input_hex VARCHAR(256) CHARACTER SET ascii NOT NULL,
    left_stored_hex VARCHAR(256) CHARACTER SET ascii NOT NULL,
    right_stored_hex VARCHAR(256) CHARACTER SET ascii NULL,
    storage_matches_input TINYINT UNSIGNED NOT NULL,
    PRIMARY KEY (case_order)
);

CREATE TEMPORARY TABLE matrix_collations (
    collation_order INT UNSIGNED NOT NULL,
    collation_name VARCHAR(64) CHARACTER SET ascii NOT NULL,
    expected_bits CHAR(7) CHARACTER SET ascii NOT NULL,
    PRIMARY KEY (collation_order)
);

INSERT INTO matrix_collations VALUES
    (1, 'utf8mb4_0900_ai_ci', '1111111'),
    (2, 'utf8mb4_0900_as_ci', '1011101'),
    (3, 'utf8mb4_0900_as_cs', '0000000'),
    (4, 'utf8mb4_ja_0900_as_cs', '0011100'),
    (5, 'utf8mb4_ja_0900_as_cs_ks', '0010100');

CREATE TEMPORARY TABLE matrix_pairs (
    pair_order INT UNSIGNED NOT NULL,
    pair_name VARCHAR(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_bin NOT NULL,
    left_value VARCHAR(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_bin NOT NULL,
    right_value VARCHAR(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_bin NOT NULL,
    PRIMARY KEY (pair_order)
);

INSERT INTO matrix_pairs VALUES
    (1, 'case', _utf8mb4'Cafe', _utf8mb4'cafe'),
    (2, 'accent', _utf8mb4'cafe', _utf8mb4'café'),
    (3, 'width-parentheses', _utf8mb4'()', _utf8mb4'（）'),
    (4, 'hiragana-katakana', _utf8mb4'かな', _utf8mb4'カナ'),
    (5, 'katakana-width', _utf8mb4'カナ', _utf8mb4'ｶﾅ'),
    (6, 'voicing', _utf8mb4'は', _utf8mb4'ば'),
    (7, 'small-kana', _utf8mb4'つ', _utf8mb4'っ');

INSERT INTO unique_test_cases (
    scope_name,
    collation_name,
    pair_name,
    left_value,
    right_value,
    expected_duplicate
)
SELECT
    'matrix',
    c.collation_name,
    p.pair_name,
    p.left_value,
    p.right_value,
    CAST(SUBSTRING(c.expected_bits, p.pair_order, 1) AS UNSIGNED)
FROM matrix_collations AS c
CROSS JOIN matrix_pairs AS p
ORDER BY c.collation_order, p.pair_order;

INSERT INTO unique_test_cases (
    scope_name,
    collation_name,
    pair_name,
    left_value,
    right_value,
    expected_duplicate
) VALUES
    ('additional', 'utf8mb4_0900_ai_ci', 'voiced-katakana-width', _utf8mb4'ガ', _utf8mb4'ｶﾞ', 1),
    ('additional', 'utf8mb4_0900_as_ci', 'voiced-katakana-width', _utf8mb4'ガ', _utf8mb4'ｶﾞ', 1),
    ('additional', 'utf8mb4_0900_as_cs', 'voiced-katakana-width', _utf8mb4'ガ', _utf8mb4'ｶﾞ', 0),
    ('additional', 'utf8mb4_ja_0900_as_cs', 'voiced-katakana-width', _utf8mb4'ガ', _utf8mb4'ｶﾞ', 0),
    ('additional', 'utf8mb4_ja_0900_as_cs_ks', 'voiced-katakana-width', _utf8mb4'ガ', _utf8mb4'ｶﾞ', 0),
    ('additional', 'utf8mb4_0900_as_cs', 'canonical-equivalent-katakana', _utf8mb4'ガ', CONVERT(0xE382ABE38299 USING utf8mb4), 1),
    ('additional', 'utf8mb4_ja_0900_as_cs', 'canonical-equivalent-katakana', _utf8mb4'ガ', CONVERT(0xE382ABE38299 USING utf8mb4), 1),
    ('additional', 'utf8mb4_0900_bin', 'canonical-equivalent-katakana', _utf8mb4'ガ', CONVERT(0xE382ABE38299 USING utf8mb4), 0),
    ('additional', 'utf8mb4_0900_as_cs', 'zero-width-space', _utf8mb4'A', CONVERT(0x41E2808B USING utf8mb4), 1),
    ('additional', 'utf8mb4_0900_bin', 'zero-width-space', _utf8mb4'A', CONVERT(0x41E2808B USING utf8mb4), 0),
    ('additional', 'utf8mb4_bin', 'trailing-space', _utf8mb4'ABC', _utf8mb4'ABC ', 1),
    ('additional', 'utf8mb4_0900_bin', 'trailing-space', _utf8mb4'ABC', _utf8mb4'ABC ', 0),
    ('additional', 'utf8mb4_ja_0900_as_cs', 'space-width', _utf8mb4' ', _utf8mb4'　', 1),
    ('additional', 'utf8mb4_general_ci', 'supplementary-plane', _utf8mb4'😀', _utf8mb4'😁', 1),
    ('additional', 'utf8mb4_unicode_ci', 'supplementary-plane', _utf8mb4'😀', _utf8mb4'😁', 1),
    ('additional', 'utf8mb4_general_ci', 'sharp-s', _utf8mb4'ß', _utf8mb4's', 1),
    ('additional', 'utf8mb4_unicode_ci', 'sharp-s-expansion', _utf8mb4'ß', _utf8mb4'ss', 1),
    ('additional', 'utf8mb4_0900_ai_ci', 'hex-alnum-width', _utf8mb4'ab12', _utf8mb4'ＡＢ１２', 1),
    ('additional', 'utf8mb4_0900_bin', 'hex-alnum-width', _utf8mb4'ab12', _utf8mb4'ＡＢ１２', 0),
    ('additional', 'utf8mb4_0900_ai_ci', 'hex-zero-width-space', _utf8mb4'deadbeef', CONVERT(0x64656164E2808B62656566 USING utf8mb4), 1),
    ('additional', 'utf8mb4_0900_bin', 'hex-zero-width-space', _utf8mb4'deadbeef', CONVERT(0x64656164E2808B62656566 USING utf8mb4), 0),
    ('additional', 'utf8mb4_0900_ai_ci', 'variation-selector', _utf8mb4'葛', CONVERT(0xE8919BF3A08480 USING utf8mb4), 1),
    ('additional', 'utf8mb4_0900_as_cs', 'variation-selector', _utf8mb4'葛', CONVERT(0xE8919BF3A08480 USING utf8mb4), 1),
    ('additional', 'utf8mb4_ja_0900_as_cs', 'variation-selector', _utf8mb4'葛', CONVERT(0xE8919BF3A08480 USING utf8mb4), 1),
    ('additional', 'utf8mb4_0900_bin', 'variation-selector', _utf8mb4'葛', CONVERT(0xE8919BF3A08480 USING utf8mb4), 0),
    ('additional', 'utf8mb4_general_ci', 'hiragana-katakana', _utf8mb4'かな', _utf8mb4'カナ', 0),
    ('additional', 'utf8mb4_unicode_ci', 'hiragana-katakana', _utf8mb4'かな', _utf8mb4'カナ', 1),
    ('additional', 'utf8mb4_general_ci', 'katakana-width', _utf8mb4'カナ', _utf8mb4'ｶﾅ', 0),
    ('additional', 'utf8mb4_unicode_ci', 'katakana-width', _utf8mb4'カナ', _utf8mb4'ｶﾅ', 1),
    ('additional', 'utf8mb4_general_ci', 'voicing', _utf8mb4'は', _utf8mb4'ば', 0),
    ('additional', 'utf8mb4_unicode_ci', 'voicing', _utf8mb4'は', _utf8mb4'ば', 1),
    ('additional', 'utf8mb4_general_ci', 'small-kana', _utf8mb4'つ', _utf8mb4'っ', 0),
    ('additional', 'utf8mb4_unicode_ci', 'small-kana', _utf8mb4'つ', _utf8mb4'っ', 1),
    ('additional', 'utf8mb4_general_ci', 'width-parentheses', _utf8mb4'()', _utf8mb4'（）', 0),
    ('additional', 'utf8mb4_unicode_ci', 'width-parentheses', _utf8mb4'()', _utf8mb4'（）', 1),
    ('additional', 'utf8mb4_general_ci', 'alnum-width', _utf8mb4'ABC123', _utf8mb4'ＡＢＣ１２３', 0),
    ('additional', 'utf8mb4_unicode_ci', 'alnum-width', _utf8mb4'ABC123', _utf8mb4'ＡＢＣ１２３', 1);

DROP PROCEDURE IF EXISTS run_unique_verification;

DELIMITER //

CREATE PROCEDURE run_unique_verification()
BEGIN
    DECLARE finished TINYINT UNSIGNED DEFAULT 0;
    DECLARE v_case_order INT UNSIGNED;
    DECLARE v_scope_name VARCHAR(16) CHARACTER SET ascii;
    DECLARE v_collation_name VARCHAR(64) CHARACTER SET ascii;
    DECLARE v_pair_name VARCHAR(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_bin;
    DECLARE v_left_value VARCHAR(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_bin;
    DECLARE v_right_value VARCHAR(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_bin;
    DECLARE v_expected_duplicate TINYINT UNSIGNED;
    DECLARE v_actual_duplicate TINYINT UNSIGNED DEFAULT 0;
    DECLARE v_left_stored_hex VARCHAR(256) CHARACTER SET ascii;
    DECLARE v_right_stored_hex VARCHAR(256) CHARACTER SET ascii;
    DECLARE v_sql TEXT CHARACTER SET utf8mb4;

    DECLARE test_cases CURSOR FOR
        SELECT
            case_order,
            scope_name,
            collation_name,
            pair_name,
            left_value,
            right_value,
            expected_duplicate
        FROM unique_test_cases
        ORDER BY case_order;
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET finished = 1;

    OPEN test_cases;

    test_loop: LOOP
        FETCH test_cases INTO
            v_case_order,
            v_scope_name,
            v_collation_name,
            v_pair_name,
            v_left_value,
            v_right_value,
            v_expected_duplicate;

        IF finished = 1 THEN
            LEAVE test_loop;
        END IF;

        IF v_collation_name NOT IN (
            'utf8mb4_0900_ai_ci',
            'utf8mb4_0900_as_ci',
            'utf8mb4_0900_as_cs',
            'utf8mb4_ja_0900_as_cs',
            'utf8mb4_ja_0900_as_cs_ks',
            'utf8mb4_0900_bin',
            'utf8mb4_bin',
            'utf8mb4_general_ci',
            'utf8mb4_unicode_ci'
        ) THEN
            SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Unexpected collation';
        END IF;

        DROP TEMPORARY TABLE IF EXISTS unique_probe;
        SET v_sql = CONCAT(
            'CREATE TEMPORARY TABLE unique_probe (',
            'id INT UNSIGNED NOT NULL AUTO_INCREMENT, ',
            'value VARCHAR(64) CHARACTER SET utf8mb4 COLLATE ',
            v_collation_name,
            ' NOT NULL, PRIMARY KEY (id), UNIQUE KEY uq_value (value)',
            ') ENGINE = InnoDB'
        );
        SET @create_probe_sql = v_sql;
        PREPARE create_probe FROM @create_probe_sql;
        EXECUTE create_probe;
        DEALLOCATE PREPARE create_probe;

        INSERT INTO unique_probe (value) VALUES (v_left_value);
        SET v_actual_duplicate = 0;

        BEGIN
            DECLARE CONTINUE HANDLER FOR 1062 SET v_actual_duplicate = 1;
            INSERT INTO unique_probe (value) VALUES (v_right_value);
        END;

        SET v_left_stored_hex = NULL;
        SET v_right_stored_hex = NULL;
        SELECT
            MAX(CASE WHEN id = 1 THEN HEX(value) END),
            MAX(CASE WHEN id = 2 THEN HEX(value) END)
        INTO v_left_stored_hex, v_right_stored_hex
        FROM unique_probe;

        INSERT INTO unique_results VALUES (
            v_case_order,
            v_scope_name,
            v_collation_name,
            v_pair_name,
            v_expected_duplicate,
            v_actual_duplicate,
            HEX(v_left_value),
            HEX(v_right_value),
            v_left_stored_hex,
            v_right_stored_hex,
            v_left_stored_hex = HEX(v_left_value)
                AND (
                    v_actual_duplicate = 1
                    OR v_right_stored_hex = HEX(v_right_value)
                )
        );

        DROP TEMPORARY TABLE unique_probe;
    END LOOP;

    CLOSE test_cases;
END//

DELIMITER ;

CALL run_unique_verification();
DROP PROCEDURE run_unique_verification;

SELECT
    COUNT(*) AS matrix_pairs,
    SUM(actual_duplicate <> expected_duplicate) AS duplicate_mismatches,
    SUM(storage_matches_input = 0) AS storage_mismatches
FROM unique_results
WHERE scope_name = 'matrix';

SELECT
    COUNT(*) AS additional_pairs,
    SUM(actual_duplicate <> expected_duplicate) AS duplicate_mismatches,
    SUM(storage_matches_input = 0) AS storage_mismatches
FROM unique_results
WHERE scope_name = 'additional';

SELECT *
FROM unique_results
WHERE actual_duplicate <> expected_duplicate
   OR storage_matches_input = 0
ORDER BY case_order;

SELECT
    scope_name,
    collation_name,
    pair_name,
    expected_duplicate,
    actual_duplicate,
    left_input_hex,
    right_input_hex,
    left_stored_hex,
    right_stored_hex,
    storage_matches_input
FROM unique_results
ORDER BY case_order;
```
### LIKE確認SQL

完全一致・逆方向・前方一致・部分一致・ワイルドカード・索引有無まで確認するSQLです。

```sql
-- MySQL 8.4 `=` and `LIKE` divergence verification for the EastBraver Labs article.
-- Run with a client configured for utf8mb4 and preserve the output as evidence.
-- This standalone SQL reports mismatches but does not make the client exit nonzero.
-- Use apps/web/scripts/verify-mysql-collation.mjs for a strict automated gate.
--
-- Scope of this script:
--   1. Expression level: `=` plus four `LIKE` forms (exact, reversed, prefix, middle).
--   2. Wildcard level: `_` counts code points, not rendered characters.
--   3. Column level: the same `LIKE` with and without an index on a real column.
--
-- Section 3 creates temporary tables only. It does not touch persistent schema.

SET NAMES utf8mb4 COLLATE utf8mb4_0900_ai_ci;

SELECT
    VERSION() AS mysql_version,
    @@version_comment AS version_comment,
    @@sql_mode AS sql_mode,
    @@character_set_client AS character_set_client,
    @@character_set_connection AS character_set_connection,
    @@character_set_results AS character_set_results,
    @@collation_connection AS collation_connection;

-- ---------------------------------------------------------------------------
-- 1. Expression level
-- ---------------------------------------------------------------------------

DROP TEMPORARY TABLE IF EXISTS like_results;

CREATE TEMPORARY TABLE like_results (
    scope_name VARCHAR(16) CHARACTER SET ascii NOT NULL,
    collation_name VARCHAR(64) CHARACTER SET ascii NOT NULL,
    pair_name VARCHAR(64) CHARACTER SET ascii NOT NULL,
    left_value VARCHAR(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_bin NOT NULL,
    right_value VARCHAR(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_bin NOT NULL,
    expected_equal TINYINT UNSIGNED NOT NULL,
    expected_like TINYINT UNSIGNED NOT NULL,
    actual_equal TINYINT UNSIGNED NOT NULL,
    like_exact TINYINT UNSIGNED NOT NULL,
    like_reversed TINYINT UNSIGNED NOT NULL,
    like_prefix TINYINT UNSIGNED NOT NULL,
    like_middle TINYINT UNSIGNED NOT NULL,
    left_hex VARCHAR(256) CHARACTER SET ascii NOT NULL,
    right_hex VARCHAR(256) CHARACTER SET ascii NOT NULL
);

-- The 35 cells of the article's main comparison matrix, now with LIKE.
-- The 71 additional rows cover expansions, contractions, ignorable
-- characters, canonical decomposition, compatibility characters, and padding.
INSERT INTO like_results VALUES
    ('matrix', 'utf8mb4_0900_ai_ci', 'case', _utf8mb4'Cafe', _utf8mb4'cafe', 1, 1,
        _utf8mb4'Cafe' COLLATE utf8mb4_0900_ai_ci = _utf8mb4'cafe',
        _utf8mb4'Cafe' COLLATE utf8mb4_0900_ai_ci LIKE _utf8mb4'cafe',
        _utf8mb4'cafe' COLLATE utf8mb4_0900_ai_ci LIKE _utf8mb4'Cafe',
        CONCAT(_utf8mb4'Cafe', _utf8mb4'zz') COLLATE utf8mb4_0900_ai_ci LIKE CONCAT(_utf8mb4'cafe', _utf8mb4'%'),
        CONCAT(_utf8mb4'zz', _utf8mb4'Cafe', _utf8mb4'zz') COLLATE utf8mb4_0900_ai_ci LIKE CONCAT(_utf8mb4'%', _utf8mb4'cafe', _utf8mb4'%'),
        HEX(_utf8mb4'Cafe'), HEX(_utf8mb4'cafe')),
    ('matrix', 'utf8mb4_0900_ai_ci', 'accent', _utf8mb4'cafe', _utf8mb4'café', 1, 1,
        _utf8mb4'cafe' COLLATE utf8mb4_0900_ai_ci = _utf8mb4'café',
        _utf8mb4'cafe' COLLATE utf8mb4_0900_ai_ci LIKE _utf8mb4'café',
        _utf8mb4'café' COLLATE utf8mb4_0900_ai_ci LIKE _utf8mb4'cafe',
        CONCAT(_utf8mb4'cafe', _utf8mb4'zz') COLLATE utf8mb4_0900_ai_ci LIKE CONCAT(_utf8mb4'café', _utf8mb4'%'),
        CONCAT(_utf8mb4'zz', _utf8mb4'cafe', _utf8mb4'zz') COLLATE utf8mb4_0900_ai_ci LIKE CONCAT(_utf8mb4'%', _utf8mb4'café', _utf8mb4'%'),
        HEX(_utf8mb4'cafe'), HEX(_utf8mb4'café')),
    ('matrix', 'utf8mb4_0900_ai_ci', 'width-parentheses', _utf8mb4'()', _utf8mb4'（）', 1, 1,
        _utf8mb4'()' COLLATE utf8mb4_0900_ai_ci = _utf8mb4'（）',
        _utf8mb4'()' COLLATE utf8mb4_0900_ai_ci LIKE _utf8mb4'（）',
        _utf8mb4'（）' COLLATE utf8mb4_0900_ai_ci LIKE _utf8mb4'()',
        CONCAT(_utf8mb4'()', _utf8mb4'zz') COLLATE utf8mb4_0900_ai_ci LIKE CONCAT(_utf8mb4'（）', _utf8mb4'%'),
        CONCAT(_utf8mb4'zz', _utf8mb4'()', _utf8mb4'zz') COLLATE utf8mb4_0900_ai_ci LIKE CONCAT(_utf8mb4'%', _utf8mb4'（）', _utf8mb4'%'),
        HEX(_utf8mb4'()'), HEX(_utf8mb4'（）')),
    ('matrix', 'utf8mb4_0900_ai_ci', 'hiragana-katakana', _utf8mb4'かな', _utf8mb4'カナ', 1, 1,
        _utf8mb4'かな' COLLATE utf8mb4_0900_ai_ci = _utf8mb4'カナ',
        _utf8mb4'かな' COLLATE utf8mb4_0900_ai_ci LIKE _utf8mb4'カナ',
        _utf8mb4'カナ' COLLATE utf8mb4_0900_ai_ci LIKE _utf8mb4'かな',
        CONCAT(_utf8mb4'かな', _utf8mb4'zz') COLLATE utf8mb4_0900_ai_ci LIKE CONCAT(_utf8mb4'カナ', _utf8mb4'%'),
        CONCAT(_utf8mb4'zz', _utf8mb4'かな', _utf8mb4'zz') COLLATE utf8mb4_0900_ai_ci LIKE CONCAT(_utf8mb4'%', _utf8mb4'カナ', _utf8mb4'%'),
        HEX(_utf8mb4'かな'), HEX(_utf8mb4'カナ')),
    ('matrix', 'utf8mb4_0900_ai_ci', 'katakana-width', _utf8mb4'カナ', _utf8mb4'ｶﾅ', 1, 1,
        _utf8mb4'カナ' COLLATE utf8mb4_0900_ai_ci = _utf8mb4'ｶﾅ',
        _utf8mb4'カナ' COLLATE utf8mb4_0900_ai_ci LIKE _utf8mb4'ｶﾅ',
        _utf8mb4'ｶﾅ' COLLATE utf8mb4_0900_ai_ci LIKE _utf8mb4'カナ',
        CONCAT(_utf8mb4'カナ', _utf8mb4'zz') COLLATE utf8mb4_0900_ai_ci LIKE CONCAT(_utf8mb4'ｶﾅ', _utf8mb4'%'),
        CONCAT(_utf8mb4'zz', _utf8mb4'カナ', _utf8mb4'zz') COLLATE utf8mb4_0900_ai_ci LIKE CONCAT(_utf8mb4'%', _utf8mb4'ｶﾅ', _utf8mb4'%'),
        HEX(_utf8mb4'カナ'), HEX(_utf8mb4'ｶﾅ')),
    ('matrix', 'utf8mb4_0900_ai_ci', 'voicing', _utf8mb4'は', _utf8mb4'ば', 1, 1,
        _utf8mb4'は' COLLATE utf8mb4_0900_ai_ci = _utf8mb4'ば',
        _utf8mb4'は' COLLATE utf8mb4_0900_ai_ci LIKE _utf8mb4'ば',
        _utf8mb4'ば' COLLATE utf8mb4_0900_ai_ci LIKE _utf8mb4'は',
        CONCAT(_utf8mb4'は', _utf8mb4'zz') COLLATE utf8mb4_0900_ai_ci LIKE CONCAT(_utf8mb4'ば', _utf8mb4'%'),
        CONCAT(_utf8mb4'zz', _utf8mb4'は', _utf8mb4'zz') COLLATE utf8mb4_0900_ai_ci LIKE CONCAT(_utf8mb4'%', _utf8mb4'ば', _utf8mb4'%'),
        HEX(_utf8mb4'は'), HEX(_utf8mb4'ば')),
    ('matrix', 'utf8mb4_0900_ai_ci', 'small-kana', _utf8mb4'つ', _utf8mb4'っ', 1, 1,
        _utf8mb4'つ' COLLATE utf8mb4_0900_ai_ci = _utf8mb4'っ',
        _utf8mb4'つ' COLLATE utf8mb4_0900_ai_ci LIKE _utf8mb4'っ',
        _utf8mb4'っ' COLLATE utf8mb4_0900_ai_ci LIKE _utf8mb4'つ',
        CONCAT(_utf8mb4'つ', _utf8mb4'zz') COLLATE utf8mb4_0900_ai_ci LIKE CONCAT(_utf8mb4'っ', _utf8mb4'%'),
        CONCAT(_utf8mb4'zz', _utf8mb4'つ', _utf8mb4'zz') COLLATE utf8mb4_0900_ai_ci LIKE CONCAT(_utf8mb4'%', _utf8mb4'っ', _utf8mb4'%'),
        HEX(_utf8mb4'つ'), HEX(_utf8mb4'っ')),
    ('matrix', 'utf8mb4_0900_as_ci', 'case', _utf8mb4'Cafe', _utf8mb4'cafe', 1, 1,
        _utf8mb4'Cafe' COLLATE utf8mb4_0900_as_ci = _utf8mb4'cafe',
        _utf8mb4'Cafe' COLLATE utf8mb4_0900_as_ci LIKE _utf8mb4'cafe',
        _utf8mb4'cafe' COLLATE utf8mb4_0900_as_ci LIKE _utf8mb4'Cafe',
        CONCAT(_utf8mb4'Cafe', _utf8mb4'zz') COLLATE utf8mb4_0900_as_ci LIKE CONCAT(_utf8mb4'cafe', _utf8mb4'%'),
        CONCAT(_utf8mb4'zz', _utf8mb4'Cafe', _utf8mb4'zz') COLLATE utf8mb4_0900_as_ci LIKE CONCAT(_utf8mb4'%', _utf8mb4'cafe', _utf8mb4'%'),
        HEX(_utf8mb4'Cafe'), HEX(_utf8mb4'cafe')),
    ('matrix', 'utf8mb4_0900_as_ci', 'accent', _utf8mb4'cafe', _utf8mb4'café', 0, 0,
        _utf8mb4'cafe' COLLATE utf8mb4_0900_as_ci = _utf8mb4'café',
        _utf8mb4'cafe' COLLATE utf8mb4_0900_as_ci LIKE _utf8mb4'café',
        _utf8mb4'café' COLLATE utf8mb4_0900_as_ci LIKE _utf8mb4'cafe',
        CONCAT(_utf8mb4'cafe', _utf8mb4'zz') COLLATE utf8mb4_0900_as_ci LIKE CONCAT(_utf8mb4'café', _utf8mb4'%'),
        CONCAT(_utf8mb4'zz', _utf8mb4'cafe', _utf8mb4'zz') COLLATE utf8mb4_0900_as_ci LIKE CONCAT(_utf8mb4'%', _utf8mb4'café', _utf8mb4'%'),
        HEX(_utf8mb4'cafe'), HEX(_utf8mb4'café')),
    ('matrix', 'utf8mb4_0900_as_ci', 'width-parentheses', _utf8mb4'()', _utf8mb4'（）', 1, 1,
        _utf8mb4'()' COLLATE utf8mb4_0900_as_ci = _utf8mb4'（）',
        _utf8mb4'()' COLLATE utf8mb4_0900_as_ci LIKE _utf8mb4'（）',
        _utf8mb4'（）' COLLATE utf8mb4_0900_as_ci LIKE _utf8mb4'()',
        CONCAT(_utf8mb4'()', _utf8mb4'zz') COLLATE utf8mb4_0900_as_ci LIKE CONCAT(_utf8mb4'（）', _utf8mb4'%'),
        CONCAT(_utf8mb4'zz', _utf8mb4'()', _utf8mb4'zz') COLLATE utf8mb4_0900_as_ci LIKE CONCAT(_utf8mb4'%', _utf8mb4'（）', _utf8mb4'%'),
        HEX(_utf8mb4'()'), HEX(_utf8mb4'（）')),
    ('matrix', 'utf8mb4_0900_as_ci', 'hiragana-katakana', _utf8mb4'かな', _utf8mb4'カナ', 1, 1,
        _utf8mb4'かな' COLLATE utf8mb4_0900_as_ci = _utf8mb4'カナ',
        _utf8mb4'かな' COLLATE utf8mb4_0900_as_ci LIKE _utf8mb4'カナ',
        _utf8mb4'カナ' COLLATE utf8mb4_0900_as_ci LIKE _utf8mb4'かな',
        CONCAT(_utf8mb4'かな', _utf8mb4'zz') COLLATE utf8mb4_0900_as_ci LIKE CONCAT(_utf8mb4'カナ', _utf8mb4'%'),
        CONCAT(_utf8mb4'zz', _utf8mb4'かな', _utf8mb4'zz') COLLATE utf8mb4_0900_as_ci LIKE CONCAT(_utf8mb4'%', _utf8mb4'カナ', _utf8mb4'%'),
        HEX(_utf8mb4'かな'), HEX(_utf8mb4'カナ')),
    ('matrix', 'utf8mb4_0900_as_ci', 'katakana-width', _utf8mb4'カナ', _utf8mb4'ｶﾅ', 1, 1,
        _utf8mb4'カナ' COLLATE utf8mb4_0900_as_ci = _utf8mb4'ｶﾅ',
        _utf8mb4'カナ' COLLATE utf8mb4_0900_as_ci LIKE _utf8mb4'ｶﾅ',
        _utf8mb4'ｶﾅ' COLLATE utf8mb4_0900_as_ci LIKE _utf8mb4'カナ',
        CONCAT(_utf8mb4'カナ', _utf8mb4'zz') COLLATE utf8mb4_0900_as_ci LIKE CONCAT(_utf8mb4'ｶﾅ', _utf8mb4'%'),
        CONCAT(_utf8mb4'zz', _utf8mb4'カナ', _utf8mb4'zz') COLLATE utf8mb4_0900_as_ci LIKE CONCAT(_utf8mb4'%', _utf8mb4'ｶﾅ', _utf8mb4'%'),
        HEX(_utf8mb4'カナ'), HEX(_utf8mb4'ｶﾅ')),
    ('matrix', 'utf8mb4_0900_as_ci', 'voicing', _utf8mb4'は', _utf8mb4'ば', 0, 0,
        _utf8mb4'は' COLLATE utf8mb4_0900_as_ci = _utf8mb4'ば',
        _utf8mb4'は' COLLATE utf8mb4_0900_as_ci LIKE _utf8mb4'ば',
        _utf8mb4'ば' COLLATE utf8mb4_0900_as_ci LIKE _utf8mb4'は',
        CONCAT(_utf8mb4'は', _utf8mb4'zz') COLLATE utf8mb4_0900_as_ci LIKE CONCAT(_utf8mb4'ば', _utf8mb4'%'),
        CONCAT(_utf8mb4'zz', _utf8mb4'は', _utf8mb4'zz') COLLATE utf8mb4_0900_as_ci LIKE CONCAT(_utf8mb4'%', _utf8mb4'ば', _utf8mb4'%'),
        HEX(_utf8mb4'は'), HEX(_utf8mb4'ば')),
    ('matrix', 'utf8mb4_0900_as_ci', 'small-kana', _utf8mb4'つ', _utf8mb4'っ', 1, 1,
        _utf8mb4'つ' COLLATE utf8mb4_0900_as_ci = _utf8mb4'っ',
        _utf8mb4'つ' COLLATE utf8mb4_0900_as_ci LIKE _utf8mb4'っ',
        _utf8mb4'っ' COLLATE utf8mb4_0900_as_ci LIKE _utf8mb4'つ',
        CONCAT(_utf8mb4'つ', _utf8mb4'zz') COLLATE utf8mb4_0900_as_ci LIKE CONCAT(_utf8mb4'っ', _utf8mb4'%'),
        CONCAT(_utf8mb4'zz', _utf8mb4'つ', _utf8mb4'zz') COLLATE utf8mb4_0900_as_ci LIKE CONCAT(_utf8mb4'%', _utf8mb4'っ', _utf8mb4'%'),
        HEX(_utf8mb4'つ'), HEX(_utf8mb4'っ')),
    ('matrix', 'utf8mb4_0900_as_cs', 'case', _utf8mb4'Cafe', _utf8mb4'cafe', 0, 0,
        _utf8mb4'Cafe' COLLATE utf8mb4_0900_as_cs = _utf8mb4'cafe',
        _utf8mb4'Cafe' COLLATE utf8mb4_0900_as_cs LIKE _utf8mb4'cafe',
        _utf8mb4'cafe' COLLATE utf8mb4_0900_as_cs LIKE _utf8mb4'Cafe',
        CONCAT(_utf8mb4'Cafe', _utf8mb4'zz') COLLATE utf8mb4_0900_as_cs LIKE CONCAT(_utf8mb4'cafe', _utf8mb4'%'),
        CONCAT(_utf8mb4'zz', _utf8mb4'Cafe', _utf8mb4'zz') COLLATE utf8mb4_0900_as_cs LIKE CONCAT(_utf8mb4'%', _utf8mb4'cafe', _utf8mb4'%'),
        HEX(_utf8mb4'Cafe'), HEX(_utf8mb4'cafe')),
    ('matrix', 'utf8mb4_0900_as_cs', 'accent', _utf8mb4'cafe', _utf8mb4'café', 0, 0,
        _utf8mb4'cafe' COLLATE utf8mb4_0900_as_cs = _utf8mb4'café',
        _utf8mb4'cafe' COLLATE utf8mb4_0900_as_cs LIKE _utf8mb4'café',
        _utf8mb4'café' COLLATE utf8mb4_0900_as_cs LIKE _utf8mb4'cafe',
        CONCAT(_utf8mb4'cafe', _utf8mb4'zz') COLLATE utf8mb4_0900_as_cs LIKE CONCAT(_utf8mb4'café', _utf8mb4'%'),
        CONCAT(_utf8mb4'zz', _utf8mb4'cafe', _utf8mb4'zz') COLLATE utf8mb4_0900_as_cs LIKE CONCAT(_utf8mb4'%', _utf8mb4'café', _utf8mb4'%'),
        HEX(_utf8mb4'cafe'), HEX(_utf8mb4'café')),
    ('matrix', 'utf8mb4_0900_as_cs', 'width-parentheses', _utf8mb4'()', _utf8mb4'（）', 0, 0,
        _utf8mb4'()' COLLATE utf8mb4_0900_as_cs = _utf8mb4'（）',
        _utf8mb4'()' COLLATE utf8mb4_0900_as_cs LIKE _utf8mb4'（）',
        _utf8mb4'（）' COLLATE utf8mb4_0900_as_cs LIKE _utf8mb4'()',
        CONCAT(_utf8mb4'()', _utf8mb4'zz') COLLATE utf8mb4_0900_as_cs LIKE CONCAT(_utf8mb4'（）', _utf8mb4'%'),
        CONCAT(_utf8mb4'zz', _utf8mb4'()', _utf8mb4'zz') COLLATE utf8mb4_0900_as_cs LIKE CONCAT(_utf8mb4'%', _utf8mb4'（）', _utf8mb4'%'),
        HEX(_utf8mb4'()'), HEX(_utf8mb4'（）')),
    ('matrix', 'utf8mb4_0900_as_cs', 'hiragana-katakana', _utf8mb4'かな', _utf8mb4'カナ', 0, 0,
        _utf8mb4'かな' COLLATE utf8mb4_0900_as_cs = _utf8mb4'カナ',
        _utf8mb4'かな' COLLATE utf8mb4_0900_as_cs LIKE _utf8mb4'カナ',
        _utf8mb4'カナ' COLLATE utf8mb4_0900_as_cs LIKE _utf8mb4'かな',
        CONCAT(_utf8mb4'かな', _utf8mb4'zz') COLLATE utf8mb4_0900_as_cs LIKE CONCAT(_utf8mb4'カナ', _utf8mb4'%'),
        CONCAT(_utf8mb4'zz', _utf8mb4'かな', _utf8mb4'zz') COLLATE utf8mb4_0900_as_cs LIKE CONCAT(_utf8mb4'%', _utf8mb4'カナ', _utf8mb4'%'),
        HEX(_utf8mb4'かな'), HEX(_utf8mb4'カナ')),
    ('matrix', 'utf8mb4_0900_as_cs', 'katakana-width', _utf8mb4'カナ', _utf8mb4'ｶﾅ', 0, 0,
        _utf8mb4'カナ' COLLATE utf8mb4_0900_as_cs = _utf8mb4'ｶﾅ',
        _utf8mb4'カナ' COLLATE utf8mb4_0900_as_cs LIKE _utf8mb4'ｶﾅ',
        _utf8mb4'ｶﾅ' COLLATE utf8mb4_0900_as_cs LIKE _utf8mb4'カナ',
        CONCAT(_utf8mb4'カナ', _utf8mb4'zz') COLLATE utf8mb4_0900_as_cs LIKE CONCAT(_utf8mb4'ｶﾅ', _utf8mb4'%'),
        CONCAT(_utf8mb4'zz', _utf8mb4'カナ', _utf8mb4'zz') COLLATE utf8mb4_0900_as_cs LIKE CONCAT(_utf8mb4'%', _utf8mb4'ｶﾅ', _utf8mb4'%'),
        HEX(_utf8mb4'カナ'), HEX(_utf8mb4'ｶﾅ')),
    ('matrix', 'utf8mb4_0900_as_cs', 'voicing', _utf8mb4'は', _utf8mb4'ば', 0, 0,
        _utf8mb4'は' COLLATE utf8mb4_0900_as_cs = _utf8mb4'ば',
        _utf8mb4'は' COLLATE utf8mb4_0900_as_cs LIKE _utf8mb4'ば',
        _utf8mb4'ば' COLLATE utf8mb4_0900_as_cs LIKE _utf8mb4'は',
        CONCAT(_utf8mb4'は', _utf8mb4'zz') COLLATE utf8mb4_0900_as_cs LIKE CONCAT(_utf8mb4'ば', _utf8mb4'%'),
        CONCAT(_utf8mb4'zz', _utf8mb4'は', _utf8mb4'zz') COLLATE utf8mb4_0900_as_cs LIKE CONCAT(_utf8mb4'%', _utf8mb4'ば', _utf8mb4'%'),
        HEX(_utf8mb4'は'), HEX(_utf8mb4'ば')),
    ('matrix', 'utf8mb4_0900_as_cs', 'small-kana', _utf8mb4'つ', _utf8mb4'っ', 0, 0,
        _utf8mb4'つ' COLLATE utf8mb4_0900_as_cs = _utf8mb4'っ',
        _utf8mb4'つ' COLLATE utf8mb4_0900_as_cs LIKE _utf8mb4'っ',
        _utf8mb4'っ' COLLATE utf8mb4_0900_as_cs LIKE _utf8mb4'つ',
        CONCAT(_utf8mb4'つ', _utf8mb4'zz') COLLATE utf8mb4_0900_as_cs LIKE CONCAT(_utf8mb4'っ', _utf8mb4'%'),
        CONCAT(_utf8mb4'zz', _utf8mb4'つ', _utf8mb4'zz') COLLATE utf8mb4_0900_as_cs LIKE CONCAT(_utf8mb4'%', _utf8mb4'っ', _utf8mb4'%'),
        HEX(_utf8mb4'つ'), HEX(_utf8mb4'っ')),
    ('matrix', 'utf8mb4_ja_0900_as_cs', 'case', _utf8mb4'Cafe', _utf8mb4'cafe', 0, 0,
        _utf8mb4'Cafe' COLLATE utf8mb4_ja_0900_as_cs = _utf8mb4'cafe',
        _utf8mb4'Cafe' COLLATE utf8mb4_ja_0900_as_cs LIKE _utf8mb4'cafe',
        _utf8mb4'cafe' COLLATE utf8mb4_ja_0900_as_cs LIKE _utf8mb4'Cafe',
        CONCAT(_utf8mb4'Cafe', _utf8mb4'zz') COLLATE utf8mb4_ja_0900_as_cs LIKE CONCAT(_utf8mb4'cafe', _utf8mb4'%'),
        CONCAT(_utf8mb4'zz', _utf8mb4'Cafe', _utf8mb4'zz') COLLATE utf8mb4_ja_0900_as_cs LIKE CONCAT(_utf8mb4'%', _utf8mb4'cafe', _utf8mb4'%'),
        HEX(_utf8mb4'Cafe'), HEX(_utf8mb4'cafe')),
    ('matrix', 'utf8mb4_ja_0900_as_cs', 'accent', _utf8mb4'cafe', _utf8mb4'café', 0, 0,
        _utf8mb4'cafe' COLLATE utf8mb4_ja_0900_as_cs = _utf8mb4'café',
        _utf8mb4'cafe' COLLATE utf8mb4_ja_0900_as_cs LIKE _utf8mb4'café',
        _utf8mb4'café' COLLATE utf8mb4_ja_0900_as_cs LIKE _utf8mb4'cafe',
        CONCAT(_utf8mb4'cafe', _utf8mb4'zz') COLLATE utf8mb4_ja_0900_as_cs LIKE CONCAT(_utf8mb4'café', _utf8mb4'%'),
        CONCAT(_utf8mb4'zz', _utf8mb4'cafe', _utf8mb4'zz') COLLATE utf8mb4_ja_0900_as_cs LIKE CONCAT(_utf8mb4'%', _utf8mb4'café', _utf8mb4'%'),
        HEX(_utf8mb4'cafe'), HEX(_utf8mb4'café')),
    ('matrix', 'utf8mb4_ja_0900_as_cs', 'width-parentheses', _utf8mb4'()', _utf8mb4'（）', 1, 1,
        _utf8mb4'()' COLLATE utf8mb4_ja_0900_as_cs = _utf8mb4'（）',
        _utf8mb4'()' COLLATE utf8mb4_ja_0900_as_cs LIKE _utf8mb4'（）',
        _utf8mb4'（）' COLLATE utf8mb4_ja_0900_as_cs LIKE _utf8mb4'()',
        CONCAT(_utf8mb4'()', _utf8mb4'zz') COLLATE utf8mb4_ja_0900_as_cs LIKE CONCAT(_utf8mb4'（）', _utf8mb4'%'),
        CONCAT(_utf8mb4'zz', _utf8mb4'()', _utf8mb4'zz') COLLATE utf8mb4_ja_0900_as_cs LIKE CONCAT(_utf8mb4'%', _utf8mb4'（）', _utf8mb4'%'),
        HEX(_utf8mb4'()'), HEX(_utf8mb4'（）')),
    ('matrix', 'utf8mb4_ja_0900_as_cs', 'hiragana-katakana', _utf8mb4'かな', _utf8mb4'カナ', 1, 1,
        _utf8mb4'かな' COLLATE utf8mb4_ja_0900_as_cs = _utf8mb4'カナ',
        _utf8mb4'かな' COLLATE utf8mb4_ja_0900_as_cs LIKE _utf8mb4'カナ',
        _utf8mb4'カナ' COLLATE utf8mb4_ja_0900_as_cs LIKE _utf8mb4'かな',
        CONCAT(_utf8mb4'かな', _utf8mb4'zz') COLLATE utf8mb4_ja_0900_as_cs LIKE CONCAT(_utf8mb4'カナ', _utf8mb4'%'),
        CONCAT(_utf8mb4'zz', _utf8mb4'かな', _utf8mb4'zz') COLLATE utf8mb4_ja_0900_as_cs LIKE CONCAT(_utf8mb4'%', _utf8mb4'カナ', _utf8mb4'%'),
        HEX(_utf8mb4'かな'), HEX(_utf8mb4'カナ')),
    ('matrix', 'utf8mb4_ja_0900_as_cs', 'katakana-width', _utf8mb4'カナ', _utf8mb4'ｶﾅ', 1, 1,
        _utf8mb4'カナ' COLLATE utf8mb4_ja_0900_as_cs = _utf8mb4'ｶﾅ',
        _utf8mb4'カナ' COLLATE utf8mb4_ja_0900_as_cs LIKE _utf8mb4'ｶﾅ',
        _utf8mb4'ｶﾅ' COLLATE utf8mb4_ja_0900_as_cs LIKE _utf8mb4'カナ',
        CONCAT(_utf8mb4'カナ', _utf8mb4'zz') COLLATE utf8mb4_ja_0900_as_cs LIKE CONCAT(_utf8mb4'ｶﾅ', _utf8mb4'%'),
        CONCAT(_utf8mb4'zz', _utf8mb4'カナ', _utf8mb4'zz') COLLATE utf8mb4_ja_0900_as_cs LIKE CONCAT(_utf8mb4'%', _utf8mb4'ｶﾅ', _utf8mb4'%'),
        HEX(_utf8mb4'カナ'), HEX(_utf8mb4'ｶﾅ')),
    ('matrix', 'utf8mb4_ja_0900_as_cs', 'voicing', _utf8mb4'は', _utf8mb4'ば', 0, 0,
        _utf8mb4'は' COLLATE utf8mb4_ja_0900_as_cs = _utf8mb4'ば',
        _utf8mb4'は' COLLATE utf8mb4_ja_0900_as_cs LIKE _utf8mb4'ば',
        _utf8mb4'ば' COLLATE utf8mb4_ja_0900_as_cs LIKE _utf8mb4'は',
        CONCAT(_utf8mb4'は', _utf8mb4'zz') COLLATE utf8mb4_ja_0900_as_cs LIKE CONCAT(_utf8mb4'ば', _utf8mb4'%'),
        CONCAT(_utf8mb4'zz', _utf8mb4'は', _utf8mb4'zz') COLLATE utf8mb4_ja_0900_as_cs LIKE CONCAT(_utf8mb4'%', _utf8mb4'ば', _utf8mb4'%'),
        HEX(_utf8mb4'は'), HEX(_utf8mb4'ば')),
    ('matrix', 'utf8mb4_ja_0900_as_cs', 'small-kana', _utf8mb4'つ', _utf8mb4'っ', 0, 0,
        _utf8mb4'つ' COLLATE utf8mb4_ja_0900_as_cs = _utf8mb4'っ',
        _utf8mb4'つ' COLLATE utf8mb4_ja_0900_as_cs LIKE _utf8mb4'っ',
        _utf8mb4'っ' COLLATE utf8mb4_ja_0900_as_cs LIKE _utf8mb4'つ',
        CONCAT(_utf8mb4'つ', _utf8mb4'zz') COLLATE utf8mb4_ja_0900_as_cs LIKE CONCAT(_utf8mb4'っ', _utf8mb4'%'),
        CONCAT(_utf8mb4'zz', _utf8mb4'つ', _utf8mb4'zz') COLLATE utf8mb4_ja_0900_as_cs LIKE CONCAT(_utf8mb4'%', _utf8mb4'っ', _utf8mb4'%'),
        HEX(_utf8mb4'つ'), HEX(_utf8mb4'っ')),
    ('matrix', 'utf8mb4_ja_0900_as_cs_ks', 'case', _utf8mb4'Cafe', _utf8mb4'cafe', 0, 0,
        _utf8mb4'Cafe' COLLATE utf8mb4_ja_0900_as_cs_ks = _utf8mb4'cafe',
        _utf8mb4'Cafe' COLLATE utf8mb4_ja_0900_as_cs_ks LIKE _utf8mb4'cafe',
        _utf8mb4'cafe' COLLATE utf8mb4_ja_0900_as_cs_ks LIKE _utf8mb4'Cafe',
        CONCAT(_utf8mb4'Cafe', _utf8mb4'zz') COLLATE utf8mb4_ja_0900_as_cs_ks LIKE CONCAT(_utf8mb4'cafe', _utf8mb4'%'),
        CONCAT(_utf8mb4'zz', _utf8mb4'Cafe', _utf8mb4'zz') COLLATE utf8mb4_ja_0900_as_cs_ks LIKE CONCAT(_utf8mb4'%', _utf8mb4'cafe', _utf8mb4'%'),
        HEX(_utf8mb4'Cafe'), HEX(_utf8mb4'cafe')),
    ('matrix', 'utf8mb4_ja_0900_as_cs_ks', 'accent', _utf8mb4'cafe', _utf8mb4'café', 0, 0,
        _utf8mb4'cafe' COLLATE utf8mb4_ja_0900_as_cs_ks = _utf8mb4'café',
        _utf8mb4'cafe' COLLATE utf8mb4_ja_0900_as_cs_ks LIKE _utf8mb4'café',
        _utf8mb4'café' COLLATE utf8mb4_ja_0900_as_cs_ks LIKE _utf8mb4'cafe',
        CONCAT(_utf8mb4'cafe', _utf8mb4'zz') COLLATE utf8mb4_ja_0900_as_cs_ks LIKE CONCAT(_utf8mb4'café', _utf8mb4'%'),
        CONCAT(_utf8mb4'zz', _utf8mb4'cafe', _utf8mb4'zz') COLLATE utf8mb4_ja_0900_as_cs_ks LIKE CONCAT(_utf8mb4'%', _utf8mb4'café', _utf8mb4'%'),
        HEX(_utf8mb4'cafe'), HEX(_utf8mb4'café')),
    ('matrix', 'utf8mb4_ja_0900_as_cs_ks', 'width-parentheses', _utf8mb4'()', _utf8mb4'（）', 1, 1,
        _utf8mb4'()' COLLATE utf8mb4_ja_0900_as_cs_ks = _utf8mb4'（）',
        _utf8mb4'()' COLLATE utf8mb4_ja_0900_as_cs_ks LIKE _utf8mb4'（）',
        _utf8mb4'（）' COLLATE utf8mb4_ja_0900_as_cs_ks LIKE _utf8mb4'()',
        CONCAT(_utf8mb4'()', _utf8mb4'zz') COLLATE utf8mb4_ja_0900_as_cs_ks LIKE CONCAT(_utf8mb4'（）', _utf8mb4'%'),
        CONCAT(_utf8mb4'zz', _utf8mb4'()', _utf8mb4'zz') COLLATE utf8mb4_ja_0900_as_cs_ks LIKE CONCAT(_utf8mb4'%', _utf8mb4'（）', _utf8mb4'%'),
        HEX(_utf8mb4'()'), HEX(_utf8mb4'（）')),
    ('matrix', 'utf8mb4_ja_0900_as_cs_ks', 'hiragana-katakana', _utf8mb4'かな', _utf8mb4'カナ', 0, 1,
        _utf8mb4'かな' COLLATE utf8mb4_ja_0900_as_cs_ks = _utf8mb4'カナ',
        _utf8mb4'かな' COLLATE utf8mb4_ja_0900_as_cs_ks LIKE _utf8mb4'カナ',
        _utf8mb4'カナ' COLLATE utf8mb4_ja_0900_as_cs_ks LIKE _utf8mb4'かな',
        CONCAT(_utf8mb4'かな', _utf8mb4'zz') COLLATE utf8mb4_ja_0900_as_cs_ks LIKE CONCAT(_utf8mb4'カナ', _utf8mb4'%'),
        CONCAT(_utf8mb4'zz', _utf8mb4'かな', _utf8mb4'zz') COLLATE utf8mb4_ja_0900_as_cs_ks LIKE CONCAT(_utf8mb4'%', _utf8mb4'カナ', _utf8mb4'%'),
        HEX(_utf8mb4'かな'), HEX(_utf8mb4'カナ')),
    ('matrix', 'utf8mb4_ja_0900_as_cs_ks', 'katakana-width', _utf8mb4'カナ', _utf8mb4'ｶﾅ', 1, 1,
        _utf8mb4'カナ' COLLATE utf8mb4_ja_0900_as_cs_ks = _utf8mb4'ｶﾅ',
        _utf8mb4'カナ' COLLATE utf8mb4_ja_0900_as_cs_ks LIKE _utf8mb4'ｶﾅ',
        _utf8mb4'ｶﾅ' COLLATE utf8mb4_ja_0900_as_cs_ks LIKE _utf8mb4'カナ',
        CONCAT(_utf8mb4'カナ', _utf8mb4'zz') COLLATE utf8mb4_ja_0900_as_cs_ks LIKE CONCAT(_utf8mb4'ｶﾅ', _utf8mb4'%'),
        CONCAT(_utf8mb4'zz', _utf8mb4'カナ', _utf8mb4'zz') COLLATE utf8mb4_ja_0900_as_cs_ks LIKE CONCAT(_utf8mb4'%', _utf8mb4'ｶﾅ', _utf8mb4'%'),
        HEX(_utf8mb4'カナ'), HEX(_utf8mb4'ｶﾅ')),
    ('matrix', 'utf8mb4_ja_0900_as_cs_ks', 'voicing', _utf8mb4'は', _utf8mb4'ば', 0, 0,
        _utf8mb4'は' COLLATE utf8mb4_ja_0900_as_cs_ks = _utf8mb4'ば',
        _utf8mb4'は' COLLATE utf8mb4_ja_0900_as_cs_ks LIKE _utf8mb4'ば',
        _utf8mb4'ば' COLLATE utf8mb4_ja_0900_as_cs_ks LIKE _utf8mb4'は',
        CONCAT(_utf8mb4'は', _utf8mb4'zz') COLLATE utf8mb4_ja_0900_as_cs_ks LIKE CONCAT(_utf8mb4'ば', _utf8mb4'%'),
        CONCAT(_utf8mb4'zz', _utf8mb4'は', _utf8mb4'zz') COLLATE utf8mb4_ja_0900_as_cs_ks LIKE CONCAT(_utf8mb4'%', _utf8mb4'ば', _utf8mb4'%'),
        HEX(_utf8mb4'は'), HEX(_utf8mb4'ば')),
    ('matrix', 'utf8mb4_ja_0900_as_cs_ks', 'small-kana', _utf8mb4'つ', _utf8mb4'っ', 0, 0,
        _utf8mb4'つ' COLLATE utf8mb4_ja_0900_as_cs_ks = _utf8mb4'っ',
        _utf8mb4'つ' COLLATE utf8mb4_ja_0900_as_cs_ks LIKE _utf8mb4'っ',
        _utf8mb4'っ' COLLATE utf8mb4_ja_0900_as_cs_ks LIKE _utf8mb4'つ',
        CONCAT(_utf8mb4'つ', _utf8mb4'zz') COLLATE utf8mb4_ja_0900_as_cs_ks LIKE CONCAT(_utf8mb4'っ', _utf8mb4'%'),
        CONCAT(_utf8mb4'zz', _utf8mb4'つ', _utf8mb4'zz') COLLATE utf8mb4_ja_0900_as_cs_ks LIKE CONCAT(_utf8mb4'%', _utf8mb4'っ', _utf8mb4'%'),
        HEX(_utf8mb4'つ'), HEX(_utf8mb4'っ')),
    ('additional', 'utf8mb4_0900_ai_ci', 'voiced-katakana-width', _utf8mb4'ガ', _utf8mb4'ｶﾞ', 1, 0,
        _utf8mb4'ガ' COLLATE utf8mb4_0900_ai_ci = _utf8mb4'ｶﾞ',
        _utf8mb4'ガ' COLLATE utf8mb4_0900_ai_ci LIKE _utf8mb4'ｶﾞ',
        _utf8mb4'ｶﾞ' COLLATE utf8mb4_0900_ai_ci LIKE _utf8mb4'ガ',
        CONCAT(_utf8mb4'ガ', _utf8mb4'zz') COLLATE utf8mb4_0900_ai_ci LIKE CONCAT(_utf8mb4'ｶﾞ', _utf8mb4'%'),
        CONCAT(_utf8mb4'zz', _utf8mb4'ガ', _utf8mb4'zz') COLLATE utf8mb4_0900_ai_ci LIKE CONCAT(_utf8mb4'%', _utf8mb4'ｶﾞ', _utf8mb4'%'),
        HEX(_utf8mb4'ガ'), HEX(_utf8mb4'ｶﾞ')),
    ('additional', 'utf8mb4_0900_as_ci', 'voiced-katakana-width', _utf8mb4'ガ', _utf8mb4'ｶﾞ', 1, 0,
        _utf8mb4'ガ' COLLATE utf8mb4_0900_as_ci = _utf8mb4'ｶﾞ',
        _utf8mb4'ガ' COLLATE utf8mb4_0900_as_ci LIKE _utf8mb4'ｶﾞ',
        _utf8mb4'ｶﾞ' COLLATE utf8mb4_0900_as_ci LIKE _utf8mb4'ガ',
        CONCAT(_utf8mb4'ガ', _utf8mb4'zz') COLLATE utf8mb4_0900_as_ci LIKE CONCAT(_utf8mb4'ｶﾞ', _utf8mb4'%'),
        CONCAT(_utf8mb4'zz', _utf8mb4'ガ', _utf8mb4'zz') COLLATE utf8mb4_0900_as_ci LIKE CONCAT(_utf8mb4'%', _utf8mb4'ｶﾞ', _utf8mb4'%'),
        HEX(_utf8mb4'ガ'), HEX(_utf8mb4'ｶﾞ')),
    ('additional', 'utf8mb4_0900_as_cs', 'voiced-katakana-width', _utf8mb4'ガ', _utf8mb4'ｶﾞ', 0, 0,
        _utf8mb4'ガ' COLLATE utf8mb4_0900_as_cs = _utf8mb4'ｶﾞ',
        _utf8mb4'ガ' COLLATE utf8mb4_0900_as_cs LIKE _utf8mb4'ｶﾞ',
        _utf8mb4'ｶﾞ' COLLATE utf8mb4_0900_as_cs LIKE _utf8mb4'ガ',
        CONCAT(_utf8mb4'ガ', _utf8mb4'zz') COLLATE utf8mb4_0900_as_cs LIKE CONCAT(_utf8mb4'ｶﾞ', _utf8mb4'%'),
        CONCAT(_utf8mb4'zz', _utf8mb4'ガ', _utf8mb4'zz') COLLATE utf8mb4_0900_as_cs LIKE CONCAT(_utf8mb4'%', _utf8mb4'ｶﾞ', _utf8mb4'%'),
        HEX(_utf8mb4'ガ'), HEX(_utf8mb4'ｶﾞ')),
    ('additional', 'utf8mb4_ja_0900_as_cs', 'voiced-katakana-width', _utf8mb4'ガ', _utf8mb4'ｶﾞ', 0, 0,
        _utf8mb4'ガ' COLLATE utf8mb4_ja_0900_as_cs = _utf8mb4'ｶﾞ',
        _utf8mb4'ガ' COLLATE utf8mb4_ja_0900_as_cs LIKE _utf8mb4'ｶﾞ',
        _utf8mb4'ｶﾞ' COLLATE utf8mb4_ja_0900_as_cs LIKE _utf8mb4'ガ',
        CONCAT(_utf8mb4'ガ', _utf8mb4'zz') COLLATE utf8mb4_ja_0900_as_cs LIKE CONCAT(_utf8mb4'ｶﾞ', _utf8mb4'%'),
        CONCAT(_utf8mb4'zz', _utf8mb4'ガ', _utf8mb4'zz') COLLATE utf8mb4_ja_0900_as_cs LIKE CONCAT(_utf8mb4'%', _utf8mb4'ｶﾞ', _utf8mb4'%'),
        HEX(_utf8mb4'ガ'), HEX(_utf8mb4'ｶﾞ')),
    ('additional', 'utf8mb4_ja_0900_as_cs_ks', 'voiced-katakana-width', _utf8mb4'ガ', _utf8mb4'ｶﾞ', 0, 0,
        _utf8mb4'ガ' COLLATE utf8mb4_ja_0900_as_cs_ks = _utf8mb4'ｶﾞ',
        _utf8mb4'ガ' COLLATE utf8mb4_ja_0900_as_cs_ks LIKE _utf8mb4'ｶﾞ',
        _utf8mb4'ｶﾞ' COLLATE utf8mb4_ja_0900_as_cs_ks LIKE _utf8mb4'ガ',
        CONCAT(_utf8mb4'ガ', _utf8mb4'zz') COLLATE utf8mb4_ja_0900_as_cs_ks LIKE CONCAT(_utf8mb4'ｶﾞ', _utf8mb4'%'),
        CONCAT(_utf8mb4'zz', _utf8mb4'ガ', _utf8mb4'zz') COLLATE utf8mb4_ja_0900_as_cs_ks LIKE CONCAT(_utf8mb4'%', _utf8mb4'ｶﾞ', _utf8mb4'%'),
        HEX(_utf8mb4'ガ'), HEX(_utf8mb4'ｶﾞ')),
    ('additional', 'utf8mb4_unicode_ci', 'voiced-katakana-width', _utf8mb4'ガ', _utf8mb4'ｶﾞ', 1, 0,
        _utf8mb4'ガ' COLLATE utf8mb4_unicode_ci = _utf8mb4'ｶﾞ',
        _utf8mb4'ガ' COLLATE utf8mb4_unicode_ci LIKE _utf8mb4'ｶﾞ',
        _utf8mb4'ｶﾞ' COLLATE utf8mb4_unicode_ci LIKE _utf8mb4'ガ',
        CONCAT(_utf8mb4'ガ', _utf8mb4'zz') COLLATE utf8mb4_unicode_ci LIKE CONCAT(_utf8mb4'ｶﾞ', _utf8mb4'%'),
        CONCAT(_utf8mb4'zz', _utf8mb4'ガ', _utf8mb4'zz') COLLATE utf8mb4_unicode_ci LIKE CONCAT(_utf8mb4'%', _utf8mb4'ｶﾞ', _utf8mb4'%'),
        HEX(_utf8mb4'ガ'), HEX(_utf8mb4'ｶﾞ')),
    ('additional', 'utf8mb4_0900_ai_ci', 'voiced-katakana-decomposed', _utf8mb4'ガ', CONVERT(0xE382ABE38299 USING utf8mb4), 1, 0,
        _utf8mb4'ガ' COLLATE utf8mb4_0900_ai_ci = CONVERT(0xE382ABE38299 USING utf8mb4),
        _utf8mb4'ガ' COLLATE utf8mb4_0900_ai_ci LIKE CONVERT(0xE382ABE38299 USING utf8mb4),
        CONVERT(0xE382ABE38299 USING utf8mb4) COLLATE utf8mb4_0900_ai_ci LIKE _utf8mb4'ガ',
        CONCAT(_utf8mb4'ガ', _utf8mb4'zz') COLLATE utf8mb4_0900_ai_ci LIKE CONCAT(CONVERT(0xE382ABE38299 USING utf8mb4), _utf8mb4'%'),
        CONCAT(_utf8mb4'zz', _utf8mb4'ガ', _utf8mb4'zz') COLLATE utf8mb4_0900_ai_ci LIKE CONCAT(_utf8mb4'%', CONVERT(0xE382ABE38299 USING utf8mb4), _utf8mb4'%'),
        HEX(_utf8mb4'ガ'), HEX(CONVERT(0xE382ABE38299 USING utf8mb4))),
    ('additional', 'utf8mb4_0900_as_ci', 'voiced-katakana-decomposed', _utf8mb4'ガ', CONVERT(0xE382ABE38299 USING utf8mb4), 1, 0,
        _utf8mb4'ガ' COLLATE utf8mb4_0900_as_ci = CONVERT(0xE382ABE38299 USING utf8mb4),
        _utf8mb4'ガ' COLLATE utf8mb4_0900_as_ci LIKE CONVERT(0xE382ABE38299 USING utf8mb4),
        CONVERT(0xE382ABE38299 USING utf8mb4) COLLATE utf8mb4_0900_as_ci LIKE _utf8mb4'ガ',
        CONCAT(_utf8mb4'ガ', _utf8mb4'zz') COLLATE utf8mb4_0900_as_ci LIKE CONCAT(CONVERT(0xE382ABE38299 USING utf8mb4), _utf8mb4'%'),
        CONCAT(_utf8mb4'zz', _utf8mb4'ガ', _utf8mb4'zz') COLLATE utf8mb4_0900_as_ci LIKE CONCAT(_utf8mb4'%', CONVERT(0xE382ABE38299 USING utf8mb4), _utf8mb4'%'),
        HEX(_utf8mb4'ガ'), HEX(CONVERT(0xE382ABE38299 USING utf8mb4))),
    ('additional', 'utf8mb4_0900_as_cs', 'voiced-katakana-decomposed', _utf8mb4'ガ', CONVERT(0xE382ABE38299 USING utf8mb4), 1, 0,
        _utf8mb4'ガ' COLLATE utf8mb4_0900_as_cs = CONVERT(0xE382ABE38299 USING utf8mb4),
        _utf8mb4'ガ' COLLATE utf8mb4_0900_as_cs LIKE CONVERT(0xE382ABE38299 USING utf8mb4),
        CONVERT(0xE382ABE38299 USING utf8mb4) COLLATE utf8mb4_0900_as_cs LIKE _utf8mb4'ガ',
        CONCAT(_utf8mb4'ガ', _utf8mb4'zz') COLLATE utf8mb4_0900_as_cs LIKE CONCAT(CONVERT(0xE382ABE38299 USING utf8mb4), _utf8mb4'%'),
        CONCAT(_utf8mb4'zz', _utf8mb4'ガ', _utf8mb4'zz') COLLATE utf8mb4_0900_as_cs LIKE CONCAT(_utf8mb4'%', CONVERT(0xE382ABE38299 USING utf8mb4), _utf8mb4'%'),
        HEX(_utf8mb4'ガ'), HEX(CONVERT(0xE382ABE38299 USING utf8mb4))),
    ('additional', 'utf8mb4_ja_0900_as_cs', 'voiced-katakana-decomposed', _utf8mb4'ガ', CONVERT(0xE382ABE38299 USING utf8mb4), 1, 0,
        _utf8mb4'ガ' COLLATE utf8mb4_ja_0900_as_cs = CONVERT(0xE382ABE38299 USING utf8mb4),
        _utf8mb4'ガ' COLLATE utf8mb4_ja_0900_as_cs LIKE CONVERT(0xE382ABE38299 USING utf8mb4),
        CONVERT(0xE382ABE38299 USING utf8mb4) COLLATE utf8mb4_ja_0900_as_cs LIKE _utf8mb4'ガ',
        CONCAT(_utf8mb4'ガ', _utf8mb4'zz') COLLATE utf8mb4_ja_0900_as_cs LIKE CONCAT(CONVERT(0xE382ABE38299 USING utf8mb4), _utf8mb4'%'),
        CONCAT(_utf8mb4'zz', _utf8mb4'ガ', _utf8mb4'zz') COLLATE utf8mb4_ja_0900_as_cs LIKE CONCAT(_utf8mb4'%', CONVERT(0xE382ABE38299 USING utf8mb4), _utf8mb4'%'),
        HEX(_utf8mb4'ガ'), HEX(CONVERT(0xE382ABE38299 USING utf8mb4))),
    ('additional', 'utf8mb4_ja_0900_as_cs_ks', 'voiced-katakana-decomposed', _utf8mb4'ガ', CONVERT(0xE382ABE38299 USING utf8mb4), 1, 0,
        _utf8mb4'ガ' COLLATE utf8mb4_ja_0900_as_cs_ks = CONVERT(0xE382ABE38299 USING utf8mb4),
        _utf8mb4'ガ' COLLATE utf8mb4_ja_0900_as_cs_ks LIKE CONVERT(0xE382ABE38299 USING utf8mb4),
        CONVERT(0xE382ABE38299 USING utf8mb4) COLLATE utf8mb4_ja_0900_as_cs_ks LIKE _utf8mb4'ガ',
        CONCAT(_utf8mb4'ガ', _utf8mb4'zz') COLLATE utf8mb4_ja_0900_as_cs_ks LIKE CONCAT(CONVERT(0xE382ABE38299 USING utf8mb4), _utf8mb4'%'),
        CONCAT(_utf8mb4'zz', _utf8mb4'ガ', _utf8mb4'zz') COLLATE utf8mb4_ja_0900_as_cs_ks LIKE CONCAT(_utf8mb4'%', CONVERT(0xE382ABE38299 USING utf8mb4), _utf8mb4'%'),
        HEX(_utf8mb4'ガ'), HEX(CONVERT(0xE382ABE38299 USING utf8mb4))),
    ('additional', 'utf8mb4_unicode_ci', 'voiced-katakana-decomposed', _utf8mb4'ガ', CONVERT(0xE382ABE38299 USING utf8mb4), 1, 0,
        _utf8mb4'ガ' COLLATE utf8mb4_unicode_ci = CONVERT(0xE382ABE38299 USING utf8mb4),
        _utf8mb4'ガ' COLLATE utf8mb4_unicode_ci LIKE CONVERT(0xE382ABE38299 USING utf8mb4),
        CONVERT(0xE382ABE38299 USING utf8mb4) COLLATE utf8mb4_unicode_ci LIKE _utf8mb4'ガ',
        CONCAT(_utf8mb4'ガ', _utf8mb4'zz') COLLATE utf8mb4_unicode_ci LIKE CONCAT(CONVERT(0xE382ABE38299 USING utf8mb4), _utf8mb4'%'),
        CONCAT(_utf8mb4'zz', _utf8mb4'ガ', _utf8mb4'zz') COLLATE utf8mb4_unicode_ci LIKE CONCAT(_utf8mb4'%', CONVERT(0xE382ABE38299 USING utf8mb4), _utf8mb4'%'),
        HEX(_utf8mb4'ガ'), HEX(CONVERT(0xE382ABE38299 USING utf8mb4))),
    ('additional', 'utf8mb4_0900_ai_ci', 'halfwidth-vs-decomposed', _utf8mb4'ｶﾞ', CONVERT(0xE382ABE38299 USING utf8mb4), 1, 1,
        _utf8mb4'ｶﾞ' COLLATE utf8mb4_0900_ai_ci = CONVERT(0xE382ABE38299 USING utf8mb4),
        _utf8mb4'ｶﾞ' COLLATE utf8mb4_0900_ai_ci LIKE CONVERT(0xE382ABE38299 USING utf8mb4),
        CONVERT(0xE382ABE38299 USING utf8mb4) COLLATE utf8mb4_0900_ai_ci LIKE _utf8mb4'ｶﾞ',
        CONCAT(_utf8mb4'ｶﾞ', _utf8mb4'zz') COLLATE utf8mb4_0900_ai_ci LIKE CONCAT(CONVERT(0xE382ABE38299 USING utf8mb4), _utf8mb4'%'),
        CONCAT(_utf8mb4'zz', _utf8mb4'ｶﾞ', _utf8mb4'zz') COLLATE utf8mb4_0900_ai_ci LIKE CONCAT(_utf8mb4'%', CONVERT(0xE382ABE38299 USING utf8mb4), _utf8mb4'%'),
        HEX(_utf8mb4'ｶﾞ'), HEX(CONVERT(0xE382ABE38299 USING utf8mb4))),
    ('additional', 'utf8mb4_0900_as_ci', 'halfwidth-vs-decomposed', _utf8mb4'ｶﾞ', CONVERT(0xE382ABE38299 USING utf8mb4), 1, 1,
        _utf8mb4'ｶﾞ' COLLATE utf8mb4_0900_as_ci = CONVERT(0xE382ABE38299 USING utf8mb4),
        _utf8mb4'ｶﾞ' COLLATE utf8mb4_0900_as_ci LIKE CONVERT(0xE382ABE38299 USING utf8mb4),
        CONVERT(0xE382ABE38299 USING utf8mb4) COLLATE utf8mb4_0900_as_ci LIKE _utf8mb4'ｶﾞ',
        CONCAT(_utf8mb4'ｶﾞ', _utf8mb4'zz') COLLATE utf8mb4_0900_as_ci LIKE CONCAT(CONVERT(0xE382ABE38299 USING utf8mb4), _utf8mb4'%'),
        CONCAT(_utf8mb4'zz', _utf8mb4'ｶﾞ', _utf8mb4'zz') COLLATE utf8mb4_0900_as_ci LIKE CONCAT(_utf8mb4'%', CONVERT(0xE382ABE38299 USING utf8mb4), _utf8mb4'%'),
        HEX(_utf8mb4'ｶﾞ'), HEX(CONVERT(0xE382ABE38299 USING utf8mb4))),
    ('additional', 'utf8mb4_0900_as_cs', 'halfwidth-vs-decomposed', _utf8mb4'ｶﾞ', CONVERT(0xE382ABE38299 USING utf8mb4), 0, 0,
        _utf8mb4'ｶﾞ' COLLATE utf8mb4_0900_as_cs = CONVERT(0xE382ABE38299 USING utf8mb4),
        _utf8mb4'ｶﾞ' COLLATE utf8mb4_0900_as_cs LIKE CONVERT(0xE382ABE38299 USING utf8mb4),
        CONVERT(0xE382ABE38299 USING utf8mb4) COLLATE utf8mb4_0900_as_cs LIKE _utf8mb4'ｶﾞ',
        CONCAT(_utf8mb4'ｶﾞ', _utf8mb4'zz') COLLATE utf8mb4_0900_as_cs LIKE CONCAT(CONVERT(0xE382ABE38299 USING utf8mb4), _utf8mb4'%'),
        CONCAT(_utf8mb4'zz', _utf8mb4'ｶﾞ', _utf8mb4'zz') COLLATE utf8mb4_0900_as_cs LIKE CONCAT(_utf8mb4'%', CONVERT(0xE382ABE38299 USING utf8mb4), _utf8mb4'%'),
        HEX(_utf8mb4'ｶﾞ'), HEX(CONVERT(0xE382ABE38299 USING utf8mb4))),
    ('additional', 'utf8mb4_ja_0900_as_cs', 'halfwidth-vs-decomposed', _utf8mb4'ｶﾞ', CONVERT(0xE382ABE38299 USING utf8mb4), 0, 0,
        _utf8mb4'ｶﾞ' COLLATE utf8mb4_ja_0900_as_cs = CONVERT(0xE382ABE38299 USING utf8mb4),
        _utf8mb4'ｶﾞ' COLLATE utf8mb4_ja_0900_as_cs LIKE CONVERT(0xE382ABE38299 USING utf8mb4),
        CONVERT(0xE382ABE38299 USING utf8mb4) COLLATE utf8mb4_ja_0900_as_cs LIKE _utf8mb4'ｶﾞ',
        CONCAT(_utf8mb4'ｶﾞ', _utf8mb4'zz') COLLATE utf8mb4_ja_0900_as_cs LIKE CONCAT(CONVERT(0xE382ABE38299 USING utf8mb4), _utf8mb4'%'),
        CONCAT(_utf8mb4'zz', _utf8mb4'ｶﾞ', _utf8mb4'zz') COLLATE utf8mb4_ja_0900_as_cs LIKE CONCAT(_utf8mb4'%', CONVERT(0xE382ABE38299 USING utf8mb4), _utf8mb4'%'),
        HEX(_utf8mb4'ｶﾞ'), HEX(CONVERT(0xE382ABE38299 USING utf8mb4))),
    ('additional', 'utf8mb4_ja_0900_as_cs_ks', 'halfwidth-vs-decomposed', _utf8mb4'ｶﾞ', CONVERT(0xE382ABE38299 USING utf8mb4), 0, 0,
        _utf8mb4'ｶﾞ' COLLATE utf8mb4_ja_0900_as_cs_ks = CONVERT(0xE382ABE38299 USING utf8mb4),
        _utf8mb4'ｶﾞ' COLLATE utf8mb4_ja_0900_as_cs_ks LIKE CONVERT(0xE382ABE38299 USING utf8mb4),
        CONVERT(0xE382ABE38299 USING utf8mb4) COLLATE utf8mb4_ja_0900_as_cs_ks LIKE _utf8mb4'ｶﾞ',
        CONCAT(_utf8mb4'ｶﾞ', _utf8mb4'zz') COLLATE utf8mb4_ja_0900_as_cs_ks LIKE CONCAT(CONVERT(0xE382ABE38299 USING utf8mb4), _utf8mb4'%'),
        CONCAT(_utf8mb4'zz', _utf8mb4'ｶﾞ', _utf8mb4'zz') COLLATE utf8mb4_ja_0900_as_cs_ks LIKE CONCAT(_utf8mb4'%', CONVERT(0xE382ABE38299 USING utf8mb4), _utf8mb4'%'),
        HEX(_utf8mb4'ｶﾞ'), HEX(CONVERT(0xE382ABE38299 USING utf8mb4))),
    ('additional', 'utf8mb4_unicode_ci', 'halfwidth-vs-decomposed', _utf8mb4'ｶﾞ', CONVERT(0xE382ABE38299 USING utf8mb4), 1, 1,
        _utf8mb4'ｶﾞ' COLLATE utf8mb4_unicode_ci = CONVERT(0xE382ABE38299 USING utf8mb4),
        _utf8mb4'ｶﾞ' COLLATE utf8mb4_unicode_ci LIKE CONVERT(0xE382ABE38299 USING utf8mb4),
        CONVERT(0xE382ABE38299 USING utf8mb4) COLLATE utf8mb4_unicode_ci LIKE _utf8mb4'ｶﾞ',
        CONCAT(_utf8mb4'ｶﾞ', _utf8mb4'zz') COLLATE utf8mb4_unicode_ci LIKE CONCAT(CONVERT(0xE382ABE38299 USING utf8mb4), _utf8mb4'%'),
        CONCAT(_utf8mb4'zz', _utf8mb4'ｶﾞ', _utf8mb4'zz') COLLATE utf8mb4_unicode_ci LIKE CONCAT(_utf8mb4'%', CONVERT(0xE382ABE38299 USING utf8mb4), _utf8mb4'%'),
        HEX(_utf8mb4'ｶﾞ'), HEX(CONVERT(0xE382ABE38299 USING utf8mb4))),
    ('additional', 'utf8mb4_0900_ai_ci', 'voiced-word-width', _utf8mb4'ｶﾞｲﾄﾞ', _utf8mb4'ガイド', 1, 0,
        _utf8mb4'ｶﾞｲﾄﾞ' COLLATE utf8mb4_0900_ai_ci = _utf8mb4'ガイド',
        _utf8mb4'ｶﾞｲﾄﾞ' COLLATE utf8mb4_0900_ai_ci LIKE _utf8mb4'ガイド',
        _utf8mb4'ガイド' COLLATE utf8mb4_0900_ai_ci LIKE _utf8mb4'ｶﾞｲﾄﾞ',
        CONCAT(_utf8mb4'ｶﾞｲﾄﾞ', _utf8mb4'zz') COLLATE utf8mb4_0900_ai_ci LIKE CONCAT(_utf8mb4'ガイド', _utf8mb4'%'),
        CONCAT(_utf8mb4'zz', _utf8mb4'ｶﾞｲﾄﾞ', _utf8mb4'zz') COLLATE utf8mb4_0900_ai_ci LIKE CONCAT(_utf8mb4'%', _utf8mb4'ガイド', _utf8mb4'%'),
        HEX(_utf8mb4'ｶﾞｲﾄﾞ'), HEX(_utf8mb4'ガイド')),
    ('additional', 'utf8mb4_0900_as_ci', 'voiced-word-width', _utf8mb4'ｶﾞｲﾄﾞ', _utf8mb4'ガイド', 1, 0,
        _utf8mb4'ｶﾞｲﾄﾞ' COLLATE utf8mb4_0900_as_ci = _utf8mb4'ガイド',
        _utf8mb4'ｶﾞｲﾄﾞ' COLLATE utf8mb4_0900_as_ci LIKE _utf8mb4'ガイド',
        _utf8mb4'ガイド' COLLATE utf8mb4_0900_as_ci LIKE _utf8mb4'ｶﾞｲﾄﾞ',
        CONCAT(_utf8mb4'ｶﾞｲﾄﾞ', _utf8mb4'zz') COLLATE utf8mb4_0900_as_ci LIKE CONCAT(_utf8mb4'ガイド', _utf8mb4'%'),
        CONCAT(_utf8mb4'zz', _utf8mb4'ｶﾞｲﾄﾞ', _utf8mb4'zz') COLLATE utf8mb4_0900_as_ci LIKE CONCAT(_utf8mb4'%', _utf8mb4'ガイド', _utf8mb4'%'),
        HEX(_utf8mb4'ｶﾞｲﾄﾞ'), HEX(_utf8mb4'ガイド')),
    ('additional', 'utf8mb4_unicode_ci', 'voiced-word-width', _utf8mb4'ｶﾞｲﾄﾞ', _utf8mb4'ガイド', 1, 0,
        _utf8mb4'ｶﾞｲﾄﾞ' COLLATE utf8mb4_unicode_ci = _utf8mb4'ガイド',
        _utf8mb4'ｶﾞｲﾄﾞ' COLLATE utf8mb4_unicode_ci LIKE _utf8mb4'ガイド',
        _utf8mb4'ガイド' COLLATE utf8mb4_unicode_ci LIKE _utf8mb4'ｶﾞｲﾄﾞ',
        CONCAT(_utf8mb4'ｶﾞｲﾄﾞ', _utf8mb4'zz') COLLATE utf8mb4_unicode_ci LIKE CONCAT(_utf8mb4'ガイド', _utf8mb4'%'),
        CONCAT(_utf8mb4'zz', _utf8mb4'ｶﾞｲﾄﾞ', _utf8mb4'zz') COLLATE utf8mb4_unicode_ci LIKE CONCAT(_utf8mb4'%', _utf8mb4'ガイド', _utf8mb4'%'),
        HEX(_utf8mb4'ｶﾞｲﾄﾞ'), HEX(_utf8mb4'ガイド')),
    ('additional', 'utf8mb4_0900_ai_ci', 'semi-voiced-katakana-width', _utf8mb4'パ', _utf8mb4'ﾊﾟ', 1, 0,
        _utf8mb4'パ' COLLATE utf8mb4_0900_ai_ci = _utf8mb4'ﾊﾟ',
        _utf8mb4'パ' COLLATE utf8mb4_0900_ai_ci LIKE _utf8mb4'ﾊﾟ',
        _utf8mb4'ﾊﾟ' COLLATE utf8mb4_0900_ai_ci LIKE _utf8mb4'パ',
        CONCAT(_utf8mb4'パ', _utf8mb4'zz') COLLATE utf8mb4_0900_ai_ci LIKE CONCAT(_utf8mb4'ﾊﾟ', _utf8mb4'%'),
        CONCAT(_utf8mb4'zz', _utf8mb4'パ', _utf8mb4'zz') COLLATE utf8mb4_0900_ai_ci LIKE CONCAT(_utf8mb4'%', _utf8mb4'ﾊﾟ', _utf8mb4'%'),
        HEX(_utf8mb4'パ'), HEX(_utf8mb4'ﾊﾟ')),
    ('additional', 'utf8mb4_unicode_ci', 'semi-voiced-katakana-width', _utf8mb4'パ', _utf8mb4'ﾊﾟ', 1, 0,
        _utf8mb4'パ' COLLATE utf8mb4_unicode_ci = _utf8mb4'ﾊﾟ',
        _utf8mb4'パ' COLLATE utf8mb4_unicode_ci LIKE _utf8mb4'ﾊﾟ',
        _utf8mb4'ﾊﾟ' COLLATE utf8mb4_unicode_ci LIKE _utf8mb4'パ',
        CONCAT(_utf8mb4'パ', _utf8mb4'zz') COLLATE utf8mb4_unicode_ci LIKE CONCAT(_utf8mb4'ﾊﾟ', _utf8mb4'%'),
        CONCAT(_utf8mb4'zz', _utf8mb4'パ', _utf8mb4'zz') COLLATE utf8mb4_unicode_ci LIKE CONCAT(_utf8mb4'%', _utf8mb4'ﾊﾟ', _utf8mb4'%'),
        HEX(_utf8mb4'パ'), HEX(_utf8mb4'ﾊﾟ')),
    ('additional', 'utf8mb4_0900_as_cs', 'semi-voiced-katakana-decomposed', _utf8mb4'パ', CONVERT(0xE3838FE3829A USING utf8mb4), 1, 0,
        _utf8mb4'パ' COLLATE utf8mb4_0900_as_cs = CONVERT(0xE3838FE3829A USING utf8mb4),
        _utf8mb4'パ' COLLATE utf8mb4_0900_as_cs LIKE CONVERT(0xE3838FE3829A USING utf8mb4),
        CONVERT(0xE3838FE3829A USING utf8mb4) COLLATE utf8mb4_0900_as_cs LIKE _utf8mb4'パ',
        CONCAT(_utf8mb4'パ', _utf8mb4'zz') COLLATE utf8mb4_0900_as_cs LIKE CONCAT(CONVERT(0xE3838FE3829A USING utf8mb4), _utf8mb4'%'),
        CONCAT(_utf8mb4'zz', _utf8mb4'パ', _utf8mb4'zz') COLLATE utf8mb4_0900_as_cs LIKE CONCAT(_utf8mb4'%', CONVERT(0xE3838FE3829A USING utf8mb4), _utf8mb4'%'),
        HEX(_utf8mb4'パ'), HEX(CONVERT(0xE3838FE3829A USING utf8mb4))),
    ('additional', 'utf8mb4_ja_0900_as_cs', 'semi-voiced-katakana-decomposed', _utf8mb4'パ', CONVERT(0xE3838FE3829A USING utf8mb4), 1, 0,
        _utf8mb4'パ' COLLATE utf8mb4_ja_0900_as_cs = CONVERT(0xE3838FE3829A USING utf8mb4),
        _utf8mb4'パ' COLLATE utf8mb4_ja_0900_as_cs LIKE CONVERT(0xE3838FE3829A USING utf8mb4),
        CONVERT(0xE3838FE3829A USING utf8mb4) COLLATE utf8mb4_ja_0900_as_cs LIKE _utf8mb4'パ',
        CONCAT(_utf8mb4'パ', _utf8mb4'zz') COLLATE utf8mb4_ja_0900_as_cs LIKE CONCAT(CONVERT(0xE3838FE3829A USING utf8mb4), _utf8mb4'%'),
        CONCAT(_utf8mb4'zz', _utf8mb4'パ', _utf8mb4'zz') COLLATE utf8mb4_ja_0900_as_cs LIKE CONCAT(_utf8mb4'%', CONVERT(0xE3838FE3829A USING utf8mb4), _utf8mb4'%'),
        HEX(_utf8mb4'パ'), HEX(CONVERT(0xE3838FE3829A USING utf8mb4))),
    ('additional', 'utf8mb4_0900_ai_ci', 'accent-decomposed', _utf8mb4'é', CONVERT(0x65CC81 USING utf8mb4), 1, 0,
        _utf8mb4'é' COLLATE utf8mb4_0900_ai_ci = CONVERT(0x65CC81 USING utf8mb4),
        _utf8mb4'é' COLLATE utf8mb4_0900_ai_ci LIKE CONVERT(0x65CC81 USING utf8mb4),
        CONVERT(0x65CC81 USING utf8mb4) COLLATE utf8mb4_0900_ai_ci LIKE _utf8mb4'é',
        CONCAT(_utf8mb4'é', _utf8mb4'zz') COLLATE utf8mb4_0900_ai_ci LIKE CONCAT(CONVERT(0x65CC81 USING utf8mb4), _utf8mb4'%'),
        CONCAT(_utf8mb4'zz', _utf8mb4'é', _utf8mb4'zz') COLLATE utf8mb4_0900_ai_ci LIKE CONCAT(_utf8mb4'%', CONVERT(0x65CC81 USING utf8mb4), _utf8mb4'%'),
        HEX(_utf8mb4'é'), HEX(CONVERT(0x65CC81 USING utf8mb4))),
    ('additional', 'utf8mb4_0900_as_cs', 'accent-decomposed', _utf8mb4'é', CONVERT(0x65CC81 USING utf8mb4), 1, 0,
        _utf8mb4'é' COLLATE utf8mb4_0900_as_cs = CONVERT(0x65CC81 USING utf8mb4),
        _utf8mb4'é' COLLATE utf8mb4_0900_as_cs LIKE CONVERT(0x65CC81 USING utf8mb4),
        CONVERT(0x65CC81 USING utf8mb4) COLLATE utf8mb4_0900_as_cs LIKE _utf8mb4'é',
        CONCAT(_utf8mb4'é', _utf8mb4'zz') COLLATE utf8mb4_0900_as_cs LIKE CONCAT(CONVERT(0x65CC81 USING utf8mb4), _utf8mb4'%'),
        CONCAT(_utf8mb4'zz', _utf8mb4'é', _utf8mb4'zz') COLLATE utf8mb4_0900_as_cs LIKE CONCAT(_utf8mb4'%', CONVERT(0x65CC81 USING utf8mb4), _utf8mb4'%'),
        HEX(_utf8mb4'é'), HEX(CONVERT(0x65CC81 USING utf8mb4))),
    ('additional', 'utf8mb4_ja_0900_as_cs', 'accent-decomposed', _utf8mb4'é', CONVERT(0x65CC81 USING utf8mb4), 1, 0,
        _utf8mb4'é' COLLATE utf8mb4_ja_0900_as_cs = CONVERT(0x65CC81 USING utf8mb4),
        _utf8mb4'é' COLLATE utf8mb4_ja_0900_as_cs LIKE CONVERT(0x65CC81 USING utf8mb4),
        CONVERT(0x65CC81 USING utf8mb4) COLLATE utf8mb4_ja_0900_as_cs LIKE _utf8mb4'é',
        CONCAT(_utf8mb4'é', _utf8mb4'zz') COLLATE utf8mb4_ja_0900_as_cs LIKE CONCAT(CONVERT(0x65CC81 USING utf8mb4), _utf8mb4'%'),
        CONCAT(_utf8mb4'zz', _utf8mb4'é', _utf8mb4'zz') COLLATE utf8mb4_ja_0900_as_cs LIKE CONCAT(_utf8mb4'%', CONVERT(0x65CC81 USING utf8mb4), _utf8mb4'%'),
        HEX(_utf8mb4'é'), HEX(CONVERT(0x65CC81 USING utf8mb4))),
    ('additional', 'utf8mb4_unicode_ci', 'accent-decomposed', _utf8mb4'é', CONVERT(0x65CC81 USING utf8mb4), 1, 0,
        _utf8mb4'é' COLLATE utf8mb4_unicode_ci = CONVERT(0x65CC81 USING utf8mb4),
        _utf8mb4'é' COLLATE utf8mb4_unicode_ci LIKE CONVERT(0x65CC81 USING utf8mb4),
        CONVERT(0x65CC81 USING utf8mb4) COLLATE utf8mb4_unicode_ci LIKE _utf8mb4'é',
        CONCAT(_utf8mb4'é', _utf8mb4'zz') COLLATE utf8mb4_unicode_ci LIKE CONCAT(CONVERT(0x65CC81 USING utf8mb4), _utf8mb4'%'),
        CONCAT(_utf8mb4'zz', _utf8mb4'é', _utf8mb4'zz') COLLATE utf8mb4_unicode_ci LIKE CONCAT(_utf8mb4'%', CONVERT(0x65CC81 USING utf8mb4), _utf8mb4'%'),
        HEX(_utf8mb4'é'), HEX(CONVERT(0x65CC81 USING utf8mb4))),
    ('additional', 'utf8mb4_0900_ai_ci', 'sharp-s-expansion', _utf8mb4'ß', _utf8mb4'ss', 1, 0,
        _utf8mb4'ß' COLLATE utf8mb4_0900_ai_ci = _utf8mb4'ss',
        _utf8mb4'ß' COLLATE utf8mb4_0900_ai_ci LIKE _utf8mb4'ss',
        _utf8mb4'ss' COLLATE utf8mb4_0900_ai_ci LIKE _utf8mb4'ß',
        CONCAT(_utf8mb4'ß', _utf8mb4'zz') COLLATE utf8mb4_0900_ai_ci LIKE CONCAT(_utf8mb4'ss', _utf8mb4'%'),
        CONCAT(_utf8mb4'zz', _utf8mb4'ß', _utf8mb4'zz') COLLATE utf8mb4_0900_ai_ci LIKE CONCAT(_utf8mb4'%', _utf8mb4'ss', _utf8mb4'%'),
        HEX(_utf8mb4'ß'), HEX(_utf8mb4'ss')),
    ('additional', 'utf8mb4_0900_as_ci', 'sharp-s-expansion', _utf8mb4'ß', _utf8mb4'ss', 0, 0,
        _utf8mb4'ß' COLLATE utf8mb4_0900_as_ci = _utf8mb4'ss',
        _utf8mb4'ß' COLLATE utf8mb4_0900_as_ci LIKE _utf8mb4'ss',
        _utf8mb4'ss' COLLATE utf8mb4_0900_as_ci LIKE _utf8mb4'ß',
        CONCAT(_utf8mb4'ß', _utf8mb4'zz') COLLATE utf8mb4_0900_as_ci LIKE CONCAT(_utf8mb4'ss', _utf8mb4'%'),
        CONCAT(_utf8mb4'zz', _utf8mb4'ß', _utf8mb4'zz') COLLATE utf8mb4_0900_as_ci LIKE CONCAT(_utf8mb4'%', _utf8mb4'ss', _utf8mb4'%'),
        HEX(_utf8mb4'ß'), HEX(_utf8mb4'ss')),
    ('additional', 'utf8mb4_unicode_ci', 'sharp-s-expansion', _utf8mb4'ß', _utf8mb4'ss', 1, 0,
        _utf8mb4'ß' COLLATE utf8mb4_unicode_ci = _utf8mb4'ss',
        _utf8mb4'ß' COLLATE utf8mb4_unicode_ci LIKE _utf8mb4'ss',
        _utf8mb4'ss' COLLATE utf8mb4_unicode_ci LIKE _utf8mb4'ß',
        CONCAT(_utf8mb4'ß', _utf8mb4'zz') COLLATE utf8mb4_unicode_ci LIKE CONCAT(_utf8mb4'ss', _utf8mb4'%'),
        CONCAT(_utf8mb4'zz', _utf8mb4'ß', _utf8mb4'zz') COLLATE utf8mb4_unicode_ci LIKE CONCAT(_utf8mb4'%', _utf8mb4'ss', _utf8mb4'%'),
        HEX(_utf8mb4'ß'), HEX(_utf8mb4'ss')),
    ('additional', 'utf8mb4_0900_ai_ci', 'compat-corporation', _utf8mb4'(株)', _utf8mb4'㈱', 1, 0,
        _utf8mb4'(株)' COLLATE utf8mb4_0900_ai_ci = _utf8mb4'㈱',
        _utf8mb4'(株)' COLLATE utf8mb4_0900_ai_ci LIKE _utf8mb4'㈱',
        _utf8mb4'㈱' COLLATE utf8mb4_0900_ai_ci LIKE _utf8mb4'(株)',
        CONCAT(_utf8mb4'(株)', _utf8mb4'zz') COLLATE utf8mb4_0900_ai_ci LIKE CONCAT(_utf8mb4'㈱', _utf8mb4'%'),
        CONCAT(_utf8mb4'zz', _utf8mb4'(株)', _utf8mb4'zz') COLLATE utf8mb4_0900_ai_ci LIKE CONCAT(_utf8mb4'%', _utf8mb4'㈱', _utf8mb4'%'),
        HEX(_utf8mb4'(株)'), HEX(_utf8mb4'㈱')),
    ('additional', 'utf8mb4_unicode_ci', 'compat-corporation', _utf8mb4'(株)', _utf8mb4'㈱', 1, 0,
        _utf8mb4'(株)' COLLATE utf8mb4_unicode_ci = _utf8mb4'㈱',
        _utf8mb4'(株)' COLLATE utf8mb4_unicode_ci LIKE _utf8mb4'㈱',
        _utf8mb4'㈱' COLLATE utf8mb4_unicode_ci LIKE _utf8mb4'(株)',
        CONCAT(_utf8mb4'(株)', _utf8mb4'zz') COLLATE utf8mb4_unicode_ci LIKE CONCAT(_utf8mb4'㈱', _utf8mb4'%'),
        CONCAT(_utf8mb4'zz', _utf8mb4'(株)', _utf8mb4'zz') COLLATE utf8mb4_unicode_ci LIKE CONCAT(_utf8mb4'%', _utf8mb4'㈱', _utf8mb4'%'),
        HEX(_utf8mb4'(株)'), HEX(_utf8mb4'㈱')),
    ('additional', 'utf8mb4_ja_0900_as_cs', 'compat-corporation', _utf8mb4'(株)', _utf8mb4'㈱', 0, 0,
        _utf8mb4'(株)' COLLATE utf8mb4_ja_0900_as_cs = _utf8mb4'㈱',
        _utf8mb4'(株)' COLLATE utf8mb4_ja_0900_as_cs LIKE _utf8mb4'㈱',
        _utf8mb4'㈱' COLLATE utf8mb4_ja_0900_as_cs LIKE _utf8mb4'(株)',
        CONCAT(_utf8mb4'(株)', _utf8mb4'zz') COLLATE utf8mb4_ja_0900_as_cs LIKE CONCAT(_utf8mb4'㈱', _utf8mb4'%'),
        CONCAT(_utf8mb4'zz', _utf8mb4'(株)', _utf8mb4'zz') COLLATE utf8mb4_ja_0900_as_cs LIKE CONCAT(_utf8mb4'%', _utf8mb4'㈱', _utf8mb4'%'),
        HEX(_utf8mb4'(株)'), HEX(_utf8mb4'㈱')),
    ('additional', 'utf8mb4_0900_ai_ci', 'compat-numero', _utf8mb4'No1', _utf8mb4'№1', 1, 0,
        _utf8mb4'No1' COLLATE utf8mb4_0900_ai_ci = _utf8mb4'№1',
        _utf8mb4'No1' COLLATE utf8mb4_0900_ai_ci LIKE _utf8mb4'№1',
        _utf8mb4'№1' COLLATE utf8mb4_0900_ai_ci LIKE _utf8mb4'No1',
        CONCAT(_utf8mb4'No1', _utf8mb4'zz') COLLATE utf8mb4_0900_ai_ci LIKE CONCAT(_utf8mb4'№1', _utf8mb4'%'),
        CONCAT(_utf8mb4'zz', _utf8mb4'No1', _utf8mb4'zz') COLLATE utf8mb4_0900_ai_ci LIKE CONCAT(_utf8mb4'%', _utf8mb4'№1', _utf8mb4'%'),
        HEX(_utf8mb4'No1'), HEX(_utf8mb4'№1')),
    ('additional', 'utf8mb4_0900_ai_ci', 'compat-ligature', _utf8mb4'fi', _utf8mb4'ﬁ', 1, 0,
        _utf8mb4'fi' COLLATE utf8mb4_0900_ai_ci = _utf8mb4'ﬁ',
        _utf8mb4'fi' COLLATE utf8mb4_0900_ai_ci LIKE _utf8mb4'ﬁ',
        _utf8mb4'ﬁ' COLLATE utf8mb4_0900_ai_ci LIKE _utf8mb4'fi',
        CONCAT(_utf8mb4'fi', _utf8mb4'zz') COLLATE utf8mb4_0900_ai_ci LIKE CONCAT(_utf8mb4'ﬁ', _utf8mb4'%'),
        CONCAT(_utf8mb4'zz', _utf8mb4'fi', _utf8mb4'zz') COLLATE utf8mb4_0900_ai_ci LIKE CONCAT(_utf8mb4'%', _utf8mb4'ﬁ', _utf8mb4'%'),
        HEX(_utf8mb4'fi'), HEX(_utf8mb4'ﬁ')),
    ('additional', 'utf8mb4_0900_ai_ci', 'compat-circled', _utf8mb4'1', _utf8mb4'①', 1, 1,
        _utf8mb4'1' COLLATE utf8mb4_0900_ai_ci = _utf8mb4'①',
        _utf8mb4'1' COLLATE utf8mb4_0900_ai_ci LIKE _utf8mb4'①',
        _utf8mb4'①' COLLATE utf8mb4_0900_ai_ci LIKE _utf8mb4'1',
        CONCAT(_utf8mb4'1', _utf8mb4'zz') COLLATE utf8mb4_0900_ai_ci LIKE CONCAT(_utf8mb4'①', _utf8mb4'%'),
        CONCAT(_utf8mb4'zz', _utf8mb4'1', _utf8mb4'zz') COLLATE utf8mb4_0900_ai_ci LIKE CONCAT(_utf8mb4'%', _utf8mb4'①', _utf8mb4'%'),
        HEX(_utf8mb4'1'), HEX(_utf8mb4'①')),
    ('additional', 'utf8mb4_ja_0900_as_cs', 'compat-circled', _utf8mb4'1', _utf8mb4'①', 0, 0,
        _utf8mb4'1' COLLATE utf8mb4_ja_0900_as_cs = _utf8mb4'①',
        _utf8mb4'1' COLLATE utf8mb4_ja_0900_as_cs LIKE _utf8mb4'①',
        _utf8mb4'①' COLLATE utf8mb4_ja_0900_as_cs LIKE _utf8mb4'1',
        CONCAT(_utf8mb4'1', _utf8mb4'zz') COLLATE utf8mb4_ja_0900_as_cs LIKE CONCAT(_utf8mb4'①', _utf8mb4'%'),
        CONCAT(_utf8mb4'zz', _utf8mb4'1', _utf8mb4'zz') COLLATE utf8mb4_ja_0900_as_cs LIKE CONCAT(_utf8mb4'%', _utf8mb4'①', _utf8mb4'%'),
        HEX(_utf8mb4'1'), HEX(_utf8mb4'①')),
    ('additional', 'utf8mb4_0900_ai_ci', 'compat-roman', _utf8mb4'I', _utf8mb4'Ⅰ', 1, 1,
        _utf8mb4'I' COLLATE utf8mb4_0900_ai_ci = _utf8mb4'Ⅰ',
        _utf8mb4'I' COLLATE utf8mb4_0900_ai_ci LIKE _utf8mb4'Ⅰ',
        _utf8mb4'Ⅰ' COLLATE utf8mb4_0900_ai_ci LIKE _utf8mb4'I',
        CONCAT(_utf8mb4'I', _utf8mb4'zz') COLLATE utf8mb4_0900_ai_ci LIKE CONCAT(_utf8mb4'Ⅰ', _utf8mb4'%'),
        CONCAT(_utf8mb4'zz', _utf8mb4'I', _utf8mb4'zz') COLLATE utf8mb4_0900_ai_ci LIKE CONCAT(_utf8mb4'%', _utf8mb4'Ⅰ', _utf8mb4'%'),
        HEX(_utf8mb4'I'), HEX(_utf8mb4'Ⅰ')),
    ('additional', 'utf8mb4_0900_as_ci', 'compat-roman', _utf8mb4'I', _utf8mb4'Ⅰ', 1, 1,
        _utf8mb4'I' COLLATE utf8mb4_0900_as_ci = _utf8mb4'Ⅰ',
        _utf8mb4'I' COLLATE utf8mb4_0900_as_ci LIKE _utf8mb4'Ⅰ',
        _utf8mb4'Ⅰ' COLLATE utf8mb4_0900_as_ci LIKE _utf8mb4'I',
        CONCAT(_utf8mb4'I', _utf8mb4'zz') COLLATE utf8mb4_0900_as_ci LIKE CONCAT(_utf8mb4'Ⅰ', _utf8mb4'%'),
        CONCAT(_utf8mb4'zz', _utf8mb4'I', _utf8mb4'zz') COLLATE utf8mb4_0900_as_ci LIKE CONCAT(_utf8mb4'%', _utf8mb4'Ⅰ', _utf8mb4'%'),
        HEX(_utf8mb4'I'), HEX(_utf8mb4'Ⅰ')),
    ('additional', 'utf8mb4_0900_ai_ci', 'zero-width-space', _utf8mb4'ab', CONVERT(0x61E2808B62 USING utf8mb4), 1, 0,
        _utf8mb4'ab' COLLATE utf8mb4_0900_ai_ci = CONVERT(0x61E2808B62 USING utf8mb4),
        _utf8mb4'ab' COLLATE utf8mb4_0900_ai_ci LIKE CONVERT(0x61E2808B62 USING utf8mb4),
        CONVERT(0x61E2808B62 USING utf8mb4) COLLATE utf8mb4_0900_ai_ci LIKE _utf8mb4'ab',
        CONCAT(_utf8mb4'ab', _utf8mb4'zz') COLLATE utf8mb4_0900_ai_ci LIKE CONCAT(CONVERT(0x61E2808B62 USING utf8mb4), _utf8mb4'%'),
        CONCAT(_utf8mb4'zz', _utf8mb4'ab', _utf8mb4'zz') COLLATE utf8mb4_0900_ai_ci LIKE CONCAT(_utf8mb4'%', CONVERT(0x61E2808B62 USING utf8mb4), _utf8mb4'%'),
        HEX(_utf8mb4'ab'), HEX(CONVERT(0x61E2808B62 USING utf8mb4))),
    ('additional', 'utf8mb4_0900_as_cs', 'zero-width-space', _utf8mb4'ab', CONVERT(0x61E2808B62 USING utf8mb4), 1, 0,
        _utf8mb4'ab' COLLATE utf8mb4_0900_as_cs = CONVERT(0x61E2808B62 USING utf8mb4),
        _utf8mb4'ab' COLLATE utf8mb4_0900_as_cs LIKE CONVERT(0x61E2808B62 USING utf8mb4),
        CONVERT(0x61E2808B62 USING utf8mb4) COLLATE utf8mb4_0900_as_cs LIKE _utf8mb4'ab',
        CONCAT(_utf8mb4'ab', _utf8mb4'zz') COLLATE utf8mb4_0900_as_cs LIKE CONCAT(CONVERT(0x61E2808B62 USING utf8mb4), _utf8mb4'%'),
        CONCAT(_utf8mb4'zz', _utf8mb4'ab', _utf8mb4'zz') COLLATE utf8mb4_0900_as_cs LIKE CONCAT(_utf8mb4'%', CONVERT(0x61E2808B62 USING utf8mb4), _utf8mb4'%'),
        HEX(_utf8mb4'ab'), HEX(CONVERT(0x61E2808B62 USING utf8mb4))),
    ('additional', 'utf8mb4_ja_0900_as_cs', 'zero-width-space', _utf8mb4'ab', CONVERT(0x61E2808B62 USING utf8mb4), 1, 0,
        _utf8mb4'ab' COLLATE utf8mb4_ja_0900_as_cs = CONVERT(0x61E2808B62 USING utf8mb4),
        _utf8mb4'ab' COLLATE utf8mb4_ja_0900_as_cs LIKE CONVERT(0x61E2808B62 USING utf8mb4),
        CONVERT(0x61E2808B62 USING utf8mb4) COLLATE utf8mb4_ja_0900_as_cs LIKE _utf8mb4'ab',
        CONCAT(_utf8mb4'ab', _utf8mb4'zz') COLLATE utf8mb4_ja_0900_as_cs LIKE CONCAT(CONVERT(0x61E2808B62 USING utf8mb4), _utf8mb4'%'),
        CONCAT(_utf8mb4'zz', _utf8mb4'ab', _utf8mb4'zz') COLLATE utf8mb4_ja_0900_as_cs LIKE CONCAT(_utf8mb4'%', CONVERT(0x61E2808B62 USING utf8mb4), _utf8mb4'%'),
        HEX(_utf8mb4'ab'), HEX(CONVERT(0x61E2808B62 USING utf8mb4))),
    ('additional', 'utf8mb4_unicode_ci', 'zero-width-space', _utf8mb4'ab', CONVERT(0x61E2808B62 USING utf8mb4), 1, 0,
        _utf8mb4'ab' COLLATE utf8mb4_unicode_ci = CONVERT(0x61E2808B62 USING utf8mb4),
        _utf8mb4'ab' COLLATE utf8mb4_unicode_ci LIKE CONVERT(0x61E2808B62 USING utf8mb4),
        CONVERT(0x61E2808B62 USING utf8mb4) COLLATE utf8mb4_unicode_ci LIKE _utf8mb4'ab',
        CONCAT(_utf8mb4'ab', _utf8mb4'zz') COLLATE utf8mb4_unicode_ci LIKE CONCAT(CONVERT(0x61E2808B62 USING utf8mb4), _utf8mb4'%'),
        CONCAT(_utf8mb4'zz', _utf8mb4'ab', _utf8mb4'zz') COLLATE utf8mb4_unicode_ci LIKE CONCAT(_utf8mb4'%', CONVERT(0x61E2808B62 USING utf8mb4), _utf8mb4'%'),
        HEX(_utf8mb4'ab'), HEX(CONVERT(0x61E2808B62 USING utf8mb4))),
    ('additional', 'utf8mb4_bin', 'trailing-space', _utf8mb4'ABC', _utf8mb4'ABC ', 1, 0,
        _utf8mb4'ABC' COLLATE utf8mb4_bin = _utf8mb4'ABC ',
        _utf8mb4'ABC' COLLATE utf8mb4_bin LIKE _utf8mb4'ABC ',
        _utf8mb4'ABC ' COLLATE utf8mb4_bin LIKE _utf8mb4'ABC',
        CONCAT(_utf8mb4'ABC', _utf8mb4'zz') COLLATE utf8mb4_bin LIKE CONCAT(_utf8mb4'ABC ', _utf8mb4'%'),
        CONCAT(_utf8mb4'zz', _utf8mb4'ABC', _utf8mb4'zz') COLLATE utf8mb4_bin LIKE CONCAT(_utf8mb4'%', _utf8mb4'ABC ', _utf8mb4'%'),
        HEX(_utf8mb4'ABC'), HEX(_utf8mb4'ABC ')),
    ('additional', 'utf8mb4_general_ci', 'trailing-space', _utf8mb4'ABC', _utf8mb4'ABC ', 1, 0,
        _utf8mb4'ABC' COLLATE utf8mb4_general_ci = _utf8mb4'ABC ',
        _utf8mb4'ABC' COLLATE utf8mb4_general_ci LIKE _utf8mb4'ABC ',
        _utf8mb4'ABC ' COLLATE utf8mb4_general_ci LIKE _utf8mb4'ABC',
        CONCAT(_utf8mb4'ABC', _utf8mb4'zz') COLLATE utf8mb4_general_ci LIKE CONCAT(_utf8mb4'ABC ', _utf8mb4'%'),
        CONCAT(_utf8mb4'zz', _utf8mb4'ABC', _utf8mb4'zz') COLLATE utf8mb4_general_ci LIKE CONCAT(_utf8mb4'%', _utf8mb4'ABC ', _utf8mb4'%'),
        HEX(_utf8mb4'ABC'), HEX(_utf8mb4'ABC ')),
    ('additional', 'utf8mb4_unicode_ci', 'trailing-space', _utf8mb4'ABC', _utf8mb4'ABC ', 1, 0,
        _utf8mb4'ABC' COLLATE utf8mb4_unicode_ci = _utf8mb4'ABC ',
        _utf8mb4'ABC' COLLATE utf8mb4_unicode_ci LIKE _utf8mb4'ABC ',
        _utf8mb4'ABC ' COLLATE utf8mb4_unicode_ci LIKE _utf8mb4'ABC',
        CONCAT(_utf8mb4'ABC', _utf8mb4'zz') COLLATE utf8mb4_unicode_ci LIKE CONCAT(_utf8mb4'ABC ', _utf8mb4'%'),
        CONCAT(_utf8mb4'zz', _utf8mb4'ABC', _utf8mb4'zz') COLLATE utf8mb4_unicode_ci LIKE CONCAT(_utf8mb4'%', _utf8mb4'ABC ', _utf8mb4'%'),
        HEX(_utf8mb4'ABC'), HEX(_utf8mb4'ABC ')),
    ('additional', 'utf8mb4_0900_bin', 'trailing-space', _utf8mb4'ABC', _utf8mb4'ABC ', 0, 0,
        _utf8mb4'ABC' COLLATE utf8mb4_0900_bin = _utf8mb4'ABC ',
        _utf8mb4'ABC' COLLATE utf8mb4_0900_bin LIKE _utf8mb4'ABC ',
        _utf8mb4'ABC ' COLLATE utf8mb4_0900_bin LIKE _utf8mb4'ABC',
        CONCAT(_utf8mb4'ABC', _utf8mb4'zz') COLLATE utf8mb4_0900_bin LIKE CONCAT(_utf8mb4'ABC ', _utf8mb4'%'),
        CONCAT(_utf8mb4'zz', _utf8mb4'ABC', _utf8mb4'zz') COLLATE utf8mb4_0900_bin LIKE CONCAT(_utf8mb4'%', _utf8mb4'ABC ', _utf8mb4'%'),
        HEX(_utf8mb4'ABC'), HEX(_utf8mb4'ABC ')),
    ('additional', 'utf8mb4_0900_ai_ci', 'trailing-space', _utf8mb4'ABC', _utf8mb4'ABC ', 0, 0,
        _utf8mb4'ABC' COLLATE utf8mb4_0900_ai_ci = _utf8mb4'ABC ',
        _utf8mb4'ABC' COLLATE utf8mb4_0900_ai_ci LIKE _utf8mb4'ABC ',
        _utf8mb4'ABC ' COLLATE utf8mb4_0900_ai_ci LIKE _utf8mb4'ABC',
        CONCAT(_utf8mb4'ABC', _utf8mb4'zz') COLLATE utf8mb4_0900_ai_ci LIKE CONCAT(_utf8mb4'ABC ', _utf8mb4'%'),
        CONCAT(_utf8mb4'zz', _utf8mb4'ABC', _utf8mb4'zz') COLLATE utf8mb4_0900_ai_ci LIKE CONCAT(_utf8mb4'%', _utf8mb4'ABC ', _utf8mb4'%'),
        HEX(_utf8mb4'ABC'), HEX(_utf8mb4'ABC ')),
    ('additional', 'utf8mb4_0900_ai_ci', 'space-width', _utf8mb4' ', _utf8mb4'　', 1, 1,
        _utf8mb4' ' COLLATE utf8mb4_0900_ai_ci = _utf8mb4'　',
        _utf8mb4' ' COLLATE utf8mb4_0900_ai_ci LIKE _utf8mb4'　',
        _utf8mb4'　' COLLATE utf8mb4_0900_ai_ci LIKE _utf8mb4' ',
        CONCAT(_utf8mb4' ', _utf8mb4'zz') COLLATE utf8mb4_0900_ai_ci LIKE CONCAT(_utf8mb4'　', _utf8mb4'%'),
        CONCAT(_utf8mb4'zz', _utf8mb4' ', _utf8mb4'zz') COLLATE utf8mb4_0900_ai_ci LIKE CONCAT(_utf8mb4'%', _utf8mb4'　', _utf8mb4'%'),
        HEX(_utf8mb4' '), HEX(_utf8mb4'　')),
    ('additional', 'utf8mb4_ja_0900_as_cs', 'space-width', _utf8mb4' ', _utf8mb4'　', 1, 1,
        _utf8mb4' ' COLLATE utf8mb4_ja_0900_as_cs = _utf8mb4'　',
        _utf8mb4' ' COLLATE utf8mb4_ja_0900_as_cs LIKE _utf8mb4'　',
        _utf8mb4'　' COLLATE utf8mb4_ja_0900_as_cs LIKE _utf8mb4' ',
        CONCAT(_utf8mb4' ', _utf8mb4'zz') COLLATE utf8mb4_ja_0900_as_cs LIKE CONCAT(_utf8mb4'　', _utf8mb4'%'),
        CONCAT(_utf8mb4'zz', _utf8mb4' ', _utf8mb4'zz') COLLATE utf8mb4_ja_0900_as_cs LIKE CONCAT(_utf8mb4'%', _utf8mb4'　', _utf8mb4'%'),
        HEX(_utf8mb4' '), HEX(_utf8mb4'　')),
    ('additional', 'utf8mb4_0900_as_cs', 'space-width', _utf8mb4' ', _utf8mb4'　', 0, 0,
        _utf8mb4' ' COLLATE utf8mb4_0900_as_cs = _utf8mb4'　',
        _utf8mb4' ' COLLATE utf8mb4_0900_as_cs LIKE _utf8mb4'　',
        _utf8mb4'　' COLLATE utf8mb4_0900_as_cs LIKE _utf8mb4' ',
        CONCAT(_utf8mb4' ', _utf8mb4'zz') COLLATE utf8mb4_0900_as_cs LIKE CONCAT(_utf8mb4'　', _utf8mb4'%'),
        CONCAT(_utf8mb4'zz', _utf8mb4' ', _utf8mb4'zz') COLLATE utf8mb4_0900_as_cs LIKE CONCAT(_utf8mb4'%', _utf8mb4'　', _utf8mb4'%'),
        HEX(_utf8mb4' '), HEX(_utf8mb4'　')),
    ('additional', 'utf8mb4_0900_ai_ci', 'alnum-width', _utf8mb4'ABC123', _utf8mb4'ＡＢＣ１２３', 1, 1,
        _utf8mb4'ABC123' COLLATE utf8mb4_0900_ai_ci = _utf8mb4'ＡＢＣ１２３',
        _utf8mb4'ABC123' COLLATE utf8mb4_0900_ai_ci LIKE _utf8mb4'ＡＢＣ１２３',
        _utf8mb4'ＡＢＣ１２３' COLLATE utf8mb4_0900_ai_ci LIKE _utf8mb4'ABC123',
        CONCAT(_utf8mb4'ABC123', _utf8mb4'zz') COLLATE utf8mb4_0900_ai_ci LIKE CONCAT(_utf8mb4'ＡＢＣ１２３', _utf8mb4'%'),
        CONCAT(_utf8mb4'zz', _utf8mb4'ABC123', _utf8mb4'zz') COLLATE utf8mb4_0900_ai_ci LIKE CONCAT(_utf8mb4'%', _utf8mb4'ＡＢＣ１２３', _utf8mb4'%'),
        HEX(_utf8mb4'ABC123'), HEX(_utf8mb4'ＡＢＣ１２３')),
    ('additional', 'utf8mb4_ja_0900_as_cs', 'alnum-width', _utf8mb4'ABC123', _utf8mb4'ＡＢＣ１２３', 1, 1,
        _utf8mb4'ABC123' COLLATE utf8mb4_ja_0900_as_cs = _utf8mb4'ＡＢＣ１２３',
        _utf8mb4'ABC123' COLLATE utf8mb4_ja_0900_as_cs LIKE _utf8mb4'ＡＢＣ１２３',
        _utf8mb4'ＡＢＣ１２３' COLLATE utf8mb4_ja_0900_as_cs LIKE _utf8mb4'ABC123',
        CONCAT(_utf8mb4'ABC123', _utf8mb4'zz') COLLATE utf8mb4_ja_0900_as_cs LIKE CONCAT(_utf8mb4'ＡＢＣ１２３', _utf8mb4'%'),
        CONCAT(_utf8mb4'zz', _utf8mb4'ABC123', _utf8mb4'zz') COLLATE utf8mb4_ja_0900_as_cs LIKE CONCAT(_utf8mb4'%', _utf8mb4'ＡＢＣ１２３', _utf8mb4'%'),
        HEX(_utf8mb4'ABC123'), HEX(_utf8mb4'ＡＢＣ１２３')),
    ('additional', 'utf8mb4_0900_ai_ci', 'product-width', _utf8mb4'商品(赤)', _utf8mb4'商品（赤）', 1, 1,
        _utf8mb4'商品(赤)' COLLATE utf8mb4_0900_ai_ci = _utf8mb4'商品（赤）',
        _utf8mb4'商品(赤)' COLLATE utf8mb4_0900_ai_ci LIKE _utf8mb4'商品（赤）',
        _utf8mb4'商品（赤）' COLLATE utf8mb4_0900_ai_ci LIKE _utf8mb4'商品(赤)',
        CONCAT(_utf8mb4'商品(赤)', _utf8mb4'zz') COLLATE utf8mb4_0900_ai_ci LIKE CONCAT(_utf8mb4'商品（赤）', _utf8mb4'%'),
        CONCAT(_utf8mb4'zz', _utf8mb4'商品(赤)', _utf8mb4'zz') COLLATE utf8mb4_0900_ai_ci LIKE CONCAT(_utf8mb4'%', _utf8mb4'商品（赤）', _utf8mb4'%'),
        HEX(_utf8mb4'商品(赤)'), HEX(_utf8mb4'商品（赤）')),
    ('additional', 'utf8mb4_ja_0900_as_cs', 'product-width', _utf8mb4'商品(赤)', _utf8mb4'商品（赤）', 1, 1,
        _utf8mb4'商品(赤)' COLLATE utf8mb4_ja_0900_as_cs = _utf8mb4'商品（赤）',
        _utf8mb4'商品(赤)' COLLATE utf8mb4_ja_0900_as_cs LIKE _utf8mb4'商品（赤）',
        _utf8mb4'商品（赤）' COLLATE utf8mb4_ja_0900_as_cs LIKE _utf8mb4'商品(赤)',
        CONCAT(_utf8mb4'商品(赤)', _utf8mb4'zz') COLLATE utf8mb4_ja_0900_as_cs LIKE CONCAT(_utf8mb4'商品（赤）', _utf8mb4'%'),
        CONCAT(_utf8mb4'zz', _utf8mb4'商品(赤)', _utf8mb4'zz') COLLATE utf8mb4_ja_0900_as_cs LIKE CONCAT(_utf8mb4'%', _utf8mb4'商品（赤）', _utf8mb4'%'),
        HEX(_utf8mb4'商品(赤)'), HEX(_utf8mb4'商品（赤）')),
    ('additional', 'utf8mb4_0900_as_cs', 'product-width', _utf8mb4'商品(赤)', _utf8mb4'商品（赤）', 0, 0,
        _utf8mb4'商品(赤)' COLLATE utf8mb4_0900_as_cs = _utf8mb4'商品（赤）',
        _utf8mb4'商品(赤)' COLLATE utf8mb4_0900_as_cs LIKE _utf8mb4'商品（赤）',
        _utf8mb4'商品（赤）' COLLATE utf8mb4_0900_as_cs LIKE _utf8mb4'商品(赤)',
        CONCAT(_utf8mb4'商品(赤)', _utf8mb4'zz') COLLATE utf8mb4_0900_as_cs LIKE CONCAT(_utf8mb4'商品（赤）', _utf8mb4'%'),
        CONCAT(_utf8mb4'zz', _utf8mb4'商品(赤)', _utf8mb4'zz') COLLATE utf8mb4_0900_as_cs LIKE CONCAT(_utf8mb4'%', _utf8mb4'商品（赤）', _utf8mb4'%'),
        HEX(_utf8mb4'商品(赤)'), HEX(_utf8mb4'商品（赤）')),
    ('additional', 'utf8mb4_0900_ai_ci', 'semi-voicing', _utf8mb4'は', _utf8mb4'ぱ', 1, 1,
        _utf8mb4'は' COLLATE utf8mb4_0900_ai_ci = _utf8mb4'ぱ',
        _utf8mb4'は' COLLATE utf8mb4_0900_ai_ci LIKE _utf8mb4'ぱ',
        _utf8mb4'ぱ' COLLATE utf8mb4_0900_ai_ci LIKE _utf8mb4'は',
        CONCAT(_utf8mb4'は', _utf8mb4'zz') COLLATE utf8mb4_0900_ai_ci LIKE CONCAT(_utf8mb4'ぱ', _utf8mb4'%'),
        CONCAT(_utf8mb4'zz', _utf8mb4'は', _utf8mb4'zz') COLLATE utf8mb4_0900_ai_ci LIKE CONCAT(_utf8mb4'%', _utf8mb4'ぱ', _utf8mb4'%'),
        HEX(_utf8mb4'は'), HEX(_utf8mb4'ぱ')),
    ('additional', 'utf8mb4_0900_as_ci', 'semi-voicing', _utf8mb4'は', _utf8mb4'ぱ', 0, 0,
        _utf8mb4'は' COLLATE utf8mb4_0900_as_ci = _utf8mb4'ぱ',
        _utf8mb4'は' COLLATE utf8mb4_0900_as_ci LIKE _utf8mb4'ぱ',
        _utf8mb4'ぱ' COLLATE utf8mb4_0900_as_ci LIKE _utf8mb4'は',
        CONCAT(_utf8mb4'は', _utf8mb4'zz') COLLATE utf8mb4_0900_as_ci LIKE CONCAT(_utf8mb4'ぱ', _utf8mb4'%'),
        CONCAT(_utf8mb4'zz', _utf8mb4'は', _utf8mb4'zz') COLLATE utf8mb4_0900_as_ci LIKE CONCAT(_utf8mb4'%', _utf8mb4'ぱ', _utf8mb4'%'),
        HEX(_utf8mb4'は'), HEX(_utf8mb4'ぱ')),
    ('additional', 'utf8mb4_0900_ai_ci', 'email-case', _utf8mb4'User@example.com', _utf8mb4'user@example.com', 1, 1,
        _utf8mb4'User@example.com' COLLATE utf8mb4_0900_ai_ci = _utf8mb4'user@example.com',
        _utf8mb4'User@example.com' COLLATE utf8mb4_0900_ai_ci LIKE _utf8mb4'user@example.com',
        _utf8mb4'user@example.com' COLLATE utf8mb4_0900_ai_ci LIKE _utf8mb4'User@example.com',
        CONCAT(_utf8mb4'User@example.com', _utf8mb4'zz') COLLATE utf8mb4_0900_ai_ci LIKE CONCAT(_utf8mb4'user@example.com', _utf8mb4'%'),
        CONCAT(_utf8mb4'zz', _utf8mb4'User@example.com', _utf8mb4'zz') COLLATE utf8mb4_0900_ai_ci LIKE CONCAT(_utf8mb4'%', _utf8mb4'user@example.com', _utf8mb4'%'),
        HEX(_utf8mb4'User@example.com'), HEX(_utf8mb4'user@example.com')),
    ('additional', 'utf8mb4_general_ci', 'case', _utf8mb4'Cafe', _utf8mb4'cafe', 1, 1,
        _utf8mb4'Cafe' COLLATE utf8mb4_general_ci = _utf8mb4'cafe',
        _utf8mb4'Cafe' COLLATE utf8mb4_general_ci LIKE _utf8mb4'cafe',
        _utf8mb4'cafe' COLLATE utf8mb4_general_ci LIKE _utf8mb4'Cafe',
        CONCAT(_utf8mb4'Cafe', _utf8mb4'zz') COLLATE utf8mb4_general_ci LIKE CONCAT(_utf8mb4'cafe', _utf8mb4'%'),
        CONCAT(_utf8mb4'zz', _utf8mb4'Cafe', _utf8mb4'zz') COLLATE utf8mb4_general_ci LIKE CONCAT(_utf8mb4'%', _utf8mb4'cafe', _utf8mb4'%'),
        HEX(_utf8mb4'Cafe'), HEX(_utf8mb4'cafe')),
    ('additional', 'utf8mb4_unicode_ci', 'case', _utf8mb4'Cafe', _utf8mb4'cafe', 1, 1,
        _utf8mb4'Cafe' COLLATE utf8mb4_unicode_ci = _utf8mb4'cafe',
        _utf8mb4'Cafe' COLLATE utf8mb4_unicode_ci LIKE _utf8mb4'cafe',
        _utf8mb4'cafe' COLLATE utf8mb4_unicode_ci LIKE _utf8mb4'Cafe',
        CONCAT(_utf8mb4'Cafe', _utf8mb4'zz') COLLATE utf8mb4_unicode_ci LIKE CONCAT(_utf8mb4'cafe', _utf8mb4'%'),
        CONCAT(_utf8mb4'zz', _utf8mb4'Cafe', _utf8mb4'zz') COLLATE utf8mb4_unicode_ci LIKE CONCAT(_utf8mb4'%', _utf8mb4'cafe', _utf8mb4'%'),
        HEX(_utf8mb4'Cafe'), HEX(_utf8mb4'cafe')),
    ('additional', 'utf8mb4_general_ci', 'accent', _utf8mb4'cafe', _utf8mb4'café', 1, 1,
        _utf8mb4'cafe' COLLATE utf8mb4_general_ci = _utf8mb4'café',
        _utf8mb4'cafe' COLLATE utf8mb4_general_ci LIKE _utf8mb4'café',
        _utf8mb4'café' COLLATE utf8mb4_general_ci LIKE _utf8mb4'cafe',
        CONCAT(_utf8mb4'cafe', _utf8mb4'zz') COLLATE utf8mb4_general_ci LIKE CONCAT(_utf8mb4'café', _utf8mb4'%'),
        CONCAT(_utf8mb4'zz', _utf8mb4'cafe', _utf8mb4'zz') COLLATE utf8mb4_general_ci LIKE CONCAT(_utf8mb4'%', _utf8mb4'café', _utf8mb4'%'),
        HEX(_utf8mb4'cafe'), HEX(_utf8mb4'café')),
    ('additional', 'utf8mb4_unicode_ci', 'accent', _utf8mb4'cafe', _utf8mb4'café', 1, 1,
        _utf8mb4'cafe' COLLATE utf8mb4_unicode_ci = _utf8mb4'café',
        _utf8mb4'cafe' COLLATE utf8mb4_unicode_ci LIKE _utf8mb4'café',
        _utf8mb4'café' COLLATE utf8mb4_unicode_ci LIKE _utf8mb4'cafe',
        CONCAT(_utf8mb4'cafe', _utf8mb4'zz') COLLATE utf8mb4_unicode_ci LIKE CONCAT(_utf8mb4'café', _utf8mb4'%'),
        CONCAT(_utf8mb4'zz', _utf8mb4'cafe', _utf8mb4'zz') COLLATE utf8mb4_unicode_ci LIKE CONCAT(_utf8mb4'%', _utf8mb4'café', _utf8mb4'%'),
        HEX(_utf8mb4'cafe'), HEX(_utf8mb4'café')),
    ('additional', 'utf8mb4_general_ci', 'voiced-katakana-width', _utf8mb4'ガ', _utf8mb4'ｶﾞ', 0, 0,
        _utf8mb4'ガ' COLLATE utf8mb4_general_ci = _utf8mb4'ｶﾞ',
        _utf8mb4'ガ' COLLATE utf8mb4_general_ci LIKE _utf8mb4'ｶﾞ',
        _utf8mb4'ｶﾞ' COLLATE utf8mb4_general_ci LIKE _utf8mb4'ガ',
        CONCAT(_utf8mb4'ガ', _utf8mb4'zz') COLLATE utf8mb4_general_ci LIKE CONCAT(_utf8mb4'ｶﾞ', _utf8mb4'%'),
        CONCAT(_utf8mb4'zz', _utf8mb4'ガ', _utf8mb4'zz') COLLATE utf8mb4_general_ci LIKE CONCAT(_utf8mb4'%', _utf8mb4'ｶﾞ', _utf8mb4'%'),
        HEX(_utf8mb4'ガ'), HEX(_utf8mb4'ｶﾞ')),
    ('additional', 'utf8mb4_general_ci', 'voiced-katakana-decomposed', _utf8mb4'ガ', CONVERT(0xE382ABE38299 USING utf8mb4), 0, 0,
        _utf8mb4'ガ' COLLATE utf8mb4_general_ci = CONVERT(0xE382ABE38299 USING utf8mb4),
        _utf8mb4'ガ' COLLATE utf8mb4_general_ci LIKE CONVERT(0xE382ABE38299 USING utf8mb4),
        CONVERT(0xE382ABE38299 USING utf8mb4) COLLATE utf8mb4_general_ci LIKE _utf8mb4'ガ',
        CONCAT(_utf8mb4'ガ', _utf8mb4'zz') COLLATE utf8mb4_general_ci LIKE CONCAT(CONVERT(0xE382ABE38299 USING utf8mb4), _utf8mb4'%'),
        CONCAT(_utf8mb4'zz', _utf8mb4'ガ', _utf8mb4'zz') COLLATE utf8mb4_general_ci LIKE CONCAT(_utf8mb4'%', CONVERT(0xE382ABE38299 USING utf8mb4), _utf8mb4'%'),
        HEX(_utf8mb4'ガ'), HEX(CONVERT(0xE382ABE38299 USING utf8mb4))),
    ('additional', 'utf8mb4_general_ci', 'sharp-s-expansion', _utf8mb4'ß', _utf8mb4'ss', 0, 0,
        _utf8mb4'ß' COLLATE utf8mb4_general_ci = _utf8mb4'ss',
        _utf8mb4'ß' COLLATE utf8mb4_general_ci LIKE _utf8mb4'ss',
        _utf8mb4'ss' COLLATE utf8mb4_general_ci LIKE _utf8mb4'ß',
        CONCAT(_utf8mb4'ß', _utf8mb4'zz') COLLATE utf8mb4_general_ci LIKE CONCAT(_utf8mb4'ss', _utf8mb4'%'),
        CONCAT(_utf8mb4'zz', _utf8mb4'ß', _utf8mb4'zz') COLLATE utf8mb4_general_ci LIKE CONCAT(_utf8mb4'%', _utf8mb4'ss', _utf8mb4'%'),
        HEX(_utf8mb4'ß'), HEX(_utf8mb4'ss')),
    ('additional', 'utf8mb4_general_ci', 'compat-corporation', _utf8mb4'(株)', _utf8mb4'㈱', 0, 0,
        _utf8mb4'(株)' COLLATE utf8mb4_general_ci = _utf8mb4'㈱',
        _utf8mb4'(株)' COLLATE utf8mb4_general_ci LIKE _utf8mb4'㈱',
        _utf8mb4'㈱' COLLATE utf8mb4_general_ci LIKE _utf8mb4'(株)',
        CONCAT(_utf8mb4'(株)', _utf8mb4'zz') COLLATE utf8mb4_general_ci LIKE CONCAT(_utf8mb4'㈱', _utf8mb4'%'),
        CONCAT(_utf8mb4'zz', _utf8mb4'(株)', _utf8mb4'zz') COLLATE utf8mb4_general_ci LIKE CONCAT(_utf8mb4'%', _utf8mb4'㈱', _utf8mb4'%'),
        HEX(_utf8mb4'(株)'), HEX(_utf8mb4'㈱')),
    ('additional', 'utf8mb4_general_ci', 'compat-circled', _utf8mb4'1', _utf8mb4'①', 0, 0,
        _utf8mb4'1' COLLATE utf8mb4_general_ci = _utf8mb4'①',
        _utf8mb4'1' COLLATE utf8mb4_general_ci LIKE _utf8mb4'①',
        _utf8mb4'①' COLLATE utf8mb4_general_ci LIKE _utf8mb4'1',
        CONCAT(_utf8mb4'1', _utf8mb4'zz') COLLATE utf8mb4_general_ci LIKE CONCAT(_utf8mb4'①', _utf8mb4'%'),
        CONCAT(_utf8mb4'zz', _utf8mb4'1', _utf8mb4'zz') COLLATE utf8mb4_general_ci LIKE CONCAT(_utf8mb4'%', _utf8mb4'①', _utf8mb4'%'),
        HEX(_utf8mb4'1'), HEX(_utf8mb4'①')),
    ('additional', 'utf8mb4_general_ci', 'zero-width-space', _utf8mb4'ab', CONVERT(0x61E2808B62 USING utf8mb4), 0, 0,
        _utf8mb4'ab' COLLATE utf8mb4_general_ci = CONVERT(0x61E2808B62 USING utf8mb4),
        _utf8mb4'ab' COLLATE utf8mb4_general_ci LIKE CONVERT(0x61E2808B62 USING utf8mb4),
        CONVERT(0x61E2808B62 USING utf8mb4) COLLATE utf8mb4_general_ci LIKE _utf8mb4'ab',
        CONCAT(_utf8mb4'ab', _utf8mb4'zz') COLLATE utf8mb4_general_ci LIKE CONCAT(CONVERT(0x61E2808B62 USING utf8mb4), _utf8mb4'%'),
        CONCAT(_utf8mb4'zz', _utf8mb4'ab', _utf8mb4'zz') COLLATE utf8mb4_general_ci LIKE CONCAT(_utf8mb4'%', CONVERT(0x61E2808B62 USING utf8mb4), _utf8mb4'%'),
        HEX(_utf8mb4'ab'), HEX(CONVERT(0x61E2808B62 USING utf8mb4))),
    ('additional', 'utf8mb4_0900_ai_ci', 'variation-selector', _utf8mb4'葛', CONVERT(0xE8919BF3A08480 USING utf8mb4), 1, 0,
        _utf8mb4'葛' COLLATE utf8mb4_0900_ai_ci = CONVERT(0xE8919BF3A08480 USING utf8mb4),
        _utf8mb4'葛' COLLATE utf8mb4_0900_ai_ci LIKE CONVERT(0xE8919BF3A08480 USING utf8mb4),
        CONVERT(0xE8919BF3A08480 USING utf8mb4) COLLATE utf8mb4_0900_ai_ci LIKE _utf8mb4'葛',
        CONCAT(_utf8mb4'葛', _utf8mb4'zz') COLLATE utf8mb4_0900_ai_ci LIKE CONCAT(CONVERT(0xE8919BF3A08480 USING utf8mb4), _utf8mb4'%'),
        CONCAT(_utf8mb4'zz', _utf8mb4'葛', _utf8mb4'zz') COLLATE utf8mb4_0900_ai_ci LIKE CONCAT(_utf8mb4'%', CONVERT(0xE8919BF3A08480 USING utf8mb4), _utf8mb4'%'),
        HEX(_utf8mb4'葛'), HEX(CONVERT(0xE8919BF3A08480 USING utf8mb4))),
    ('additional', 'utf8mb4_0900_as_cs', 'variation-selector', _utf8mb4'葛', CONVERT(0xE8919BF3A08480 USING utf8mb4), 1, 0,
        _utf8mb4'葛' COLLATE utf8mb4_0900_as_cs = CONVERT(0xE8919BF3A08480 USING utf8mb4),
        _utf8mb4'葛' COLLATE utf8mb4_0900_as_cs LIKE CONVERT(0xE8919BF3A08480 USING utf8mb4),
        CONVERT(0xE8919BF3A08480 USING utf8mb4) COLLATE utf8mb4_0900_as_cs LIKE _utf8mb4'葛',
        CONCAT(_utf8mb4'葛', _utf8mb4'zz') COLLATE utf8mb4_0900_as_cs LIKE CONCAT(CONVERT(0xE8919BF3A08480 USING utf8mb4), _utf8mb4'%'),
        CONCAT(_utf8mb4'zz', _utf8mb4'葛', _utf8mb4'zz') COLLATE utf8mb4_0900_as_cs LIKE CONCAT(_utf8mb4'%', CONVERT(0xE8919BF3A08480 USING utf8mb4), _utf8mb4'%'),
        HEX(_utf8mb4'葛'), HEX(CONVERT(0xE8919BF3A08480 USING utf8mb4))),
    ('additional', 'utf8mb4_ja_0900_as_cs', 'variation-selector', _utf8mb4'葛', CONVERT(0xE8919BF3A08480 USING utf8mb4), 1, 0,
        _utf8mb4'葛' COLLATE utf8mb4_ja_0900_as_cs = CONVERT(0xE8919BF3A08480 USING utf8mb4),
        _utf8mb4'葛' COLLATE utf8mb4_ja_0900_as_cs LIKE CONVERT(0xE8919BF3A08480 USING utf8mb4),
        CONVERT(0xE8919BF3A08480 USING utf8mb4) COLLATE utf8mb4_ja_0900_as_cs LIKE _utf8mb4'葛',
        CONCAT(_utf8mb4'葛', _utf8mb4'zz') COLLATE utf8mb4_ja_0900_as_cs LIKE CONCAT(CONVERT(0xE8919BF3A08480 USING utf8mb4), _utf8mb4'%'),
        CONCAT(_utf8mb4'zz', _utf8mb4'葛', _utf8mb4'zz') COLLATE utf8mb4_ja_0900_as_cs LIKE CONCAT(_utf8mb4'%', CONVERT(0xE8919BF3A08480 USING utf8mb4), _utf8mb4'%'),
        HEX(_utf8mb4'葛'), HEX(CONVERT(0xE8919BF3A08480 USING utf8mb4)));

SELECT
    COUNT(*) AS matrix_cells,
    SUM(actual_equal <> expected_equal) AS matrix_equal_mismatches,
    SUM(like_exact <> expected_like
        OR like_reversed <> expected_like
        OR like_prefix <> expected_like
        OR like_middle <> expected_like) AS matrix_like_mismatches,
    SUM(expected_equal <> expected_like) AS matrix_divergent_cells
FROM like_results
WHERE scope_name = 'matrix';

SELECT
    COUNT(*) AS additional_checks,
    SUM(actual_equal <> expected_equal) AS additional_equal_mismatches,
    SUM(like_exact <> expected_like
        OR like_reversed <> expected_like
        OR like_prefix <> expected_like
        OR like_middle <> expected_like) AS additional_like_mismatches,
    SUM(expected_equal <> expected_like) AS additional_divergent_cells
FROM like_results
WHERE scope_name = 'additional';

SELECT *
FROM like_results
WHERE actual_equal <> expected_equal
   OR like_exact <> expected_like
   OR like_reversed <> expected_like
   OR like_prefix <> expected_like
   OR like_middle <> expected_like
ORDER BY scope_name, collation_name, pair_name;

SELECT
    scope_name,
    collation_name,
    pair_name,
    expected_equal,
    actual_equal,
    expected_like,
    like_exact,
    like_reversed,
    like_prefix,
    like_middle,
    left_hex,
    right_hex
FROM like_results
ORDER BY scope_name, collation_name, pair_name;

-- ---------------------------------------------------------------------------
-- 2. Wildcard level
-- ---------------------------------------------------------------------------

DROP TEMPORARY TABLE IF EXISTS like_wildcard_results;

CREATE TEMPORARY TABLE like_wildcard_results (
    case_name VARCHAR(64) CHARACTER SET ascii NOT NULL,
    collation_name VARCHAR(64) CHARACTER SET ascii NOT NULL,
    subject_value VARCHAR(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_bin NOT NULL,
    pattern_value VARCHAR(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_bin NOT NULL,
    expected_match TINYINT UNSIGNED NOT NULL,
    actual_match TINYINT UNSIGNED NOT NULL,
    subject_hex VARCHAR(256) CHARACTER SET ascii NOT NULL
);

INSERT INTO like_wildcard_results VALUES
    ('single-underscore-precomposed', 'utf8mb4_0900_ai_ci', _utf8mb4'ガ', _utf8mb4'_', 1,
        _utf8mb4'ガ' COLLATE utf8mb4_0900_ai_ci LIKE _utf8mb4'_',
        HEX(_utf8mb4'ガ')),
    ('single-underscore-halfwidth', 'utf8mb4_0900_ai_ci', _utf8mb4'ｶﾞ', _utf8mb4'_', 0,
        _utf8mb4'ｶﾞ' COLLATE utf8mb4_0900_ai_ci LIKE _utf8mb4'_',
        HEX(_utf8mb4'ｶﾞ')),
    ('double-underscore-halfwidth', 'utf8mb4_0900_ai_ci', _utf8mb4'ｶﾞ', _utf8mb4'__', 1,
        _utf8mb4'ｶﾞ' COLLATE utf8mb4_0900_ai_ci LIKE _utf8mb4'__',
        HEX(_utf8mb4'ｶﾞ')),
    ('double-underscore-precomposed', 'utf8mb4_0900_ai_ci', _utf8mb4'ガ', _utf8mb4'__', 0,
        _utf8mb4'ガ' COLLATE utf8mb4_0900_ai_ci LIKE _utf8mb4'__',
        HEX(_utf8mb4'ガ')),
    ('zero-width-space-counted', 'utf8mb4_0900_ai_ci', CONVERT(0x61E2808B62 USING utf8mb4), _utf8mb4'___', 1,
        CONVERT(0x61E2808B62 USING utf8mb4) COLLATE utf8mb4_0900_ai_ci LIKE _utf8mb4'___',
        HEX(CONVERT(0x61E2808B62 USING utf8mb4))),
    ('plain-two-characters', 'utf8mb4_0900_ai_ci', _utf8mb4'ab', _utf8mb4'___', 0,
        _utf8mb4'ab' COLLATE utf8mb4_0900_ai_ci LIKE _utf8mb4'___',
        HEX(_utf8mb4'ab'));

SELECT
    COUNT(*) AS wildcard_checks,
    SUM(actual_match <> expected_match) AS wildcard_mismatches
FROM like_wildcard_results;

SELECT
    case_name,
    collation_name,
    pattern_value,
    expected_match,
    actual_match,
    subject_hex
FROM like_wildcard_results
ORDER BY case_name;

-- ---------------------------------------------------------------------------
-- 3. Column level, with and without an index
-- ---------------------------------------------------------------------------

DROP TEMPORARY TABLE IF EXISTS like_kana_indexed;
DROP TEMPORARY TABLE IF EXISTS like_product_indexed;
DROP TEMPORARY TABLE IF EXISTS like_pad_indexed;
DROP TEMPORARY TABLE IF EXISTS like_query_results;

-- utf8mb4_ja_0900_as_cs_ks separates hiragana from katakana for `=` and UNIQUE.
CREATE TEMPORARY TABLE like_kana_indexed (
    id INT UNSIGNED NOT NULL AUTO_INCREMENT,
    value VARCHAR(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_ja_0900_as_cs_ks NOT NULL,
    PRIMARY KEY (id),
    UNIQUE KEY uq_value (value)
) ENGINE = InnoDB;

INSERT INTO like_kana_indexed (value) VALUES (_utf8mb4'かな'), (_utf8mb4'カナ');

CREATE TEMPORARY TABLE like_product_indexed (
    id INT UNSIGNED NOT NULL AUTO_INCREMENT,
    name VARCHAR(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
    PRIMARY KEY (id),
    KEY k_name (name)
) ENGINE = InnoDB;

INSERT INTO like_product_indexed (name) VALUES
    (_utf8mb4'ガイドブック'),
    (_utf8mb4'ｶﾞｲﾄﾞﾌﾞｯｸ'),
    (_utf8mb4'カナ手帳'),
    (_utf8mb4'ｶﾅ手帳'),
    (_utf8mb4'Café Latte'),
    (_utf8mb4'(株)東'),
    (_utf8mb4'㈱東'),
    (_utf8mb4'ABC '),
    (_utf8mb4'ABC'),
    (_utf8mb4'ab'),
    (CONVERT(0x61E2808B62 USING utf8mb4)),
    (_utf8mb4'ß'),
    (_utf8mb4'ss'),
    (_utf8mb4'葛飾'),
    (CONVERT(0xE8919BF3A08480E9A3BE USING utf8mb4));

-- utf8mb4_bin is PAD SPACE, so `=` ignores the trailing space while LIKE does not.
CREATE TEMPORARY TABLE like_pad_indexed (
    id INT UNSIGNED NOT NULL AUTO_INCREMENT,
    value VARCHAR(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL,
    PRIMARY KEY (id),
    KEY k_value (value)
) ENGINE = InnoDB;

INSERT INTO like_pad_indexed (value) VALUES (_utf8mb4'ABC'), (_utf8mb4'ABC ');

CREATE TEMPORARY TABLE like_query_results (
    case_name VARCHAR(64) CHARACTER SET ascii NOT NULL,
    index_path VARCHAR(16) CHARACTER SET ascii NOT NULL,
    expected_ids VARCHAR(64) CHARACTER SET ascii NOT NULL,
    actual_ids VARCHAR(64) CHARACTER SET ascii NOT NULL
);

INSERT INTO like_query_results
SELECT 'kana-equal', 'index', '1', IFNULL(GROUP_CONCAT(id ORDER BY id), '')
FROM like_kana_indexed
WHERE value = _utf8mb4'かな';

INSERT INTO like_query_results
SELECT 'kana-like-exact', 'index', '1', IFNULL(GROUP_CONCAT(id ORDER BY id), '')
FROM like_kana_indexed
WHERE value LIKE _utf8mb4'かな';

INSERT INTO like_query_results
SELECT 'kana-like-exact', 'ignore', '1,2', IFNULL(GROUP_CONCAT(id ORDER BY id), '')
FROM like_kana_indexed IGNORE INDEX (uq_value)
WHERE value LIKE _utf8mb4'かな';

INSERT INTO like_query_results
SELECT 'kana-like-prefix', 'index', '1,2', IFNULL(GROUP_CONCAT(id ORDER BY id), '')
FROM like_kana_indexed
WHERE value LIKE _utf8mb4'かな%';

INSERT INTO like_query_results
SELECT 'kana-like-prefix', 'ignore', '1,2', IFNULL(GROUP_CONCAT(id ORDER BY id), '')
FROM like_kana_indexed IGNORE INDEX (uq_value)
WHERE value LIKE _utf8mb4'かな%';

INSERT INTO like_query_results
SELECT 'kana-like-middle', 'index', '1,2', IFNULL(GROUP_CONCAT(id ORDER BY id), '')
FROM like_kana_indexed
WHERE value LIKE _utf8mb4'%かな%';

INSERT INTO like_query_results
SELECT 'kana-both-rows-stored', 'index', '1,2', IFNULL(GROUP_CONCAT(id ORDER BY id), '')
FROM like_kana_indexed
WHERE 1 = 1;

INSERT INTO like_query_results
SELECT 'product-equal-guidebook', 'index', '1,2', IFNULL(GROUP_CONCAT(id ORDER BY id), '')
FROM like_product_indexed
WHERE name = _utf8mb4'ガイドブック';

INSERT INTO like_query_results
SELECT 'product-like-guidebook', 'index', '1', IFNULL(GROUP_CONCAT(id ORDER BY id), '')
FROM like_product_indexed
WHERE name LIKE _utf8mb4'ガイドブック';

INSERT INTO like_query_results
SELECT 'product-like-guide-prefix', 'index', '1', IFNULL(GROUP_CONCAT(id ORDER BY id), '')
FROM like_product_indexed
WHERE name LIKE _utf8mb4'ガイド%';

INSERT INTO like_query_results
SELECT 'product-like-guide-prefix', 'ignore', '1', IFNULL(GROUP_CONCAT(id ORDER BY id), '')
FROM like_product_indexed IGNORE INDEX (k_name)
WHERE name LIKE _utf8mb4'ガイド%';

INSERT INTO like_query_results
SELECT 'product-like-halfwidth-middle', 'index', '2', IFNULL(GROUP_CONCAT(id ORDER BY id), '')
FROM like_product_indexed
WHERE name LIKE _utf8mb4'%ｶﾞｲﾄﾞ%';

INSERT INTO like_query_results
SELECT 'product-like-kana-prefix', 'index', '3,4', IFNULL(GROUP_CONCAT(id ORDER BY id), '')
FROM like_product_indexed
WHERE name LIKE _utf8mb4'カナ%';

INSERT INTO like_query_results
SELECT 'product-like-cafe-prefix', 'index', '5', IFNULL(GROUP_CONCAT(id ORDER BY id), '')
FROM like_product_indexed
WHERE name LIKE _utf8mb4'cafe%';

INSERT INTO like_query_results
SELECT 'product-equal-corporation', 'index', '6,7', IFNULL(GROUP_CONCAT(id ORDER BY id), '')
FROM like_product_indexed
WHERE name = _utf8mb4'(株)東';

INSERT INTO like_query_results
SELECT 'product-like-corporation-prefix', 'index', '6', IFNULL(GROUP_CONCAT(id ORDER BY id), '')
FROM like_product_indexed
WHERE name LIKE _utf8mb4'(株)%';

INSERT INTO like_query_results
SELECT 'product-equal-trailing-space', 'index', '9', IFNULL(GROUP_CONCAT(id ORDER BY id), '')
FROM like_product_indexed
WHERE name = _utf8mb4'ABC';

INSERT INTO like_query_results
SELECT 'product-like-trailing-space', 'index', '9', IFNULL(GROUP_CONCAT(id ORDER BY id), '')
FROM like_product_indexed
WHERE name LIKE _utf8mb4'ABC';

-- The index only changes the result where LIKE matches more rows than `=`.
INSERT INTO like_query_results
SELECT 'kana-like-single-prefix', 'index', '1,2', IFNULL(GROUP_CONCAT(id ORDER BY id), '')
FROM like_kana_indexed
WHERE value LIKE _utf8mb4'か%';

INSERT INTO like_query_results
SELECT 'kana-like-single-prefix', 'ignore', '1,2', IFNULL(GROUP_CONCAT(id ORDER BY id), '')
FROM like_kana_indexed IGNORE INDEX (uq_value)
WHERE value LIKE _utf8mb4'か%';

INSERT INTO like_query_results
SELECT 'product-like-guidebook', 'ignore', '1', IFNULL(GROUP_CONCAT(id ORDER BY id), '')
FROM like_product_indexed IGNORE INDEX (k_name)
WHERE name LIKE _utf8mb4'ガイドブック';

INSERT INTO like_query_results
SELECT 'product-like-corporation-prefix', 'ignore', '6', IFNULL(GROUP_CONCAT(id ORDER BY id), '')
FROM like_product_indexed IGNORE INDEX (k_name)
WHERE name LIKE _utf8mb4'(株)%';

INSERT INTO like_query_results
SELECT 'product-like-trailing-space', 'ignore', '9', IFNULL(GROUP_CONCAT(id ORDER BY id), '')
FROM like_product_indexed IGNORE INDEX (k_name)
WHERE name LIKE _utf8mb4'ABC';

INSERT INTO like_query_results
SELECT 'product-like-zero-width-space', 'index', '10', IFNULL(GROUP_CONCAT(id ORDER BY id), '')
FROM like_product_indexed
WHERE name LIKE _utf8mb4'ab';

INSERT INTO like_query_results
SELECT 'product-like-zero-width-space', 'ignore', '10', IFNULL(GROUP_CONCAT(id ORDER BY id), '')
FROM like_product_indexed IGNORE INDEX (k_name)
WHERE name LIKE _utf8mb4'ab';

INSERT INTO like_query_results
SELECT 'product-like-sharp-s', 'index', '12', IFNULL(GROUP_CONCAT(id ORDER BY id), '')
FROM like_product_indexed
WHERE name LIKE _utf8mb4'ß';

INSERT INTO like_query_results
SELECT 'product-like-sharp-s', 'ignore', '12', IFNULL(GROUP_CONCAT(id ORDER BY id), '')
FROM like_product_indexed IGNORE INDEX (k_name)
WHERE name LIKE _utf8mb4'ß';

INSERT INTO like_query_results
SELECT 'product-equal-variation-selector', 'index', '14,15', IFNULL(GROUP_CONCAT(id ORDER BY id), '')
FROM like_product_indexed
WHERE name = _utf8mb4'葛飾';

INSERT INTO like_query_results
SELECT 'product-like-variation-selector', 'index', '14', IFNULL(GROUP_CONCAT(id ORDER BY id), '')
FROM like_product_indexed
WHERE name LIKE _utf8mb4'葛飾%';

INSERT INTO like_query_results
SELECT 'product-like-variation-selector', 'ignore', '14', IFNULL(GROUP_CONCAT(id ORDER BY id), '')
FROM like_product_indexed IGNORE INDEX (k_name)
WHERE name LIKE _utf8mb4'葛飾%';

INSERT INTO like_query_results
SELECT 'pad-equal-trailing-space', 'index', '1,2', IFNULL(GROUP_CONCAT(id ORDER BY id), '')
FROM like_pad_indexed
WHERE value = _utf8mb4'ABC';

INSERT INTO like_query_results
SELECT 'pad-like-trailing-space', 'index', '1', IFNULL(GROUP_CONCAT(id ORDER BY id), '')
FROM like_pad_indexed
WHERE value LIKE _utf8mb4'ABC';

INSERT INTO like_query_results
SELECT 'pad-like-trailing-space', 'ignore', '1', IFNULL(GROUP_CONCAT(id ORDER BY id), '')
FROM like_pad_indexed IGNORE INDEX (k_value)
WHERE value LIKE _utf8mb4'ABC';

SELECT
    COUNT(*) AS query_checks,
    SUM(actual_ids <> expected_ids) AS query_mismatches
FROM like_query_results;

SELECT
    case_name,
    index_path,
    expected_ids,
    actual_ids
FROM like_query_results
ORDER BY case_name, index_path;

DROP TEMPORARY TABLE IF EXISTS like_kana_indexed;
DROP TEMPORARY TABLE IF EXISTS like_product_indexed;
DROP TEMPORARY TABLE IF EXISTS like_pad_indexed;
DROP TEMPORARY TABLE IF EXISTS like_query_results;
DROP TEMPORARY TABLE IF EXISTS like_wildcard_results;
DROP TEMPORARY TABLE IF EXISTS like_results;
```
3つのSQLは期待値と実測値の不一致件数を出力します。
UNIQUE確認SQLは通常の `INSERT` を使い、エラー番号1062を重複として記録します。
受け入れられた行は `HEX()` で入力値と保存値を照合します。
LIKE確認SQLは、完全一致・逆方向・前方一致・部分一致の4式、`_` によるコードポイント数の確認、索引を使う場合と `IGNORE INDEX` を付けた場合の列検索を含みます。

収録SQLは結果表を返しますが、不一致時にmysqlクライアントを非ゼロ終了させる自動判定ゲートではありません。
自動化する場合は、期待件数・不一致・NULL・途中終了を別の処理で判定してください。

実行条件と各ケースの実測値は[公開検証結果](/downloads/mysql-collation-unique-width/verification-results.json)から確認できる
以下の条件と件数は このJSONの記録に対応する

| 実行条件 | 値 |
|---|---|
| サーバー | MySQL 8.4.11 Community Server - GPL |
| OS・アーキテクチャ | `linux/arm64` |
| イメージ | `mysql:8.4.11` |
| イメージダイジェスト | `sha256:85b9bf2e29cf836ecb8c2a15a935d4ba0c606631dff1dd79531a11983c638f2a` |
| ストレージエンジン | InnoDB |
| SQLモード | `ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION` |
| 接続文字セット | client・connection・resultsともに `utf8mb4` |
| 接続照合順序 | `utf8mb4_0900_ai_ci` |
| 比較SQL | 主表35セル・追加37件とも不一致0件 |
| UNIQUE確認SQL | 主表35組・追加37組とも判定不一致0件・保存HEX不一致0件 |
| LIKE確認SQL | 主表35セル・追加74件・ワイルドカード6件・列検索33件とも不一致0件 |
| 独立試験 | 比較124件・UNIQUE 124組・LIKE 69件・ワイルドカード6件とも不一致0件 |
| 本文の個別確認 | 47件中不一致0件 |
| 反証用の改変試験 | 7件すべてを検証器が拒否 |

表の「不一致0件」は 各式の実測値が期待値と一致したという意味であり `=` と `LIKE` が同じ結果だったという意味ではない
両演算子の結果が分かれたのは 主表の `utf8mb4_ja_0900_as_cs_ks` における `かな` / `カナ` の1セルと 追加ケースの36件で 合計37件だった
収録3本のSQLは 表に示した公式Dockerイメージでの実行結果とSQLのSHA-256が公開JSONの記録に一致している
独立試験・本文の個別確認・反証用の改変試験の結果は 公開JSONの記録に基づく

UNIQUE確認SQLは、一時テーブルと検証用の通常のストアドプロシージャを作成します。
プロシージャは正常終了時に削除しますが、途中停止時は残る可能性があります。
冒頭の `DROP PROCEDURE IF EXISTS run_unique_verification` は同名の既存プロシージャを削除するため、既存DBではなく専用の検証環境で実行してください。
LIKE確認SQLは一時テーブルだけを作成し、持続するスキーマには触れません。

次は個別の比較方法を示す短い例です。

```sql
-- 1：同等、0：異なる
SELECT
    _utf8mb4'商品(赤)' COLLATE utf8mb4_0900_ai_ci
        = _utf8mb4'商品（赤）' AS default_width_equal,   -- 1
    _utf8mb4'商品(赤)' COLLATE utf8mb4_0900_as_cs
        = _utf8mb4'商品（赤）' AS as_cs_width_equal,     -- 0
    _utf8mb4'商品(赤)' COLLATE utf8mb4_ja_0900_as_cs
        = _utf8mb4'商品（赤）' AS ja_width_equal;        -- 1

SELECT
    _utf8mb4'かな' COLLATE utf8mb4_ja_0900_as_cs_ks
        = _utf8mb4'カナ' AS kana_equal,                 -- 0
    _utf8mb4'カナ' COLLATE utf8mb4_ja_0900_as_cs_ks
        = _utf8mb4'ｶﾅ' AS katakana_width_equal;         -- 1

-- 同じ組を LIKE で比較すると結果が変わります。
SELECT
    _utf8mb4'かな' COLLATE utf8mb4_ja_0900_as_cs_ks
        LIKE _utf8mb4'カナ' AS kana_like,               -- 1
    _utf8mb4'ガ' COLLATE utf8mb4_0900_ai_ci
        = _utf8mb4'ｶﾞ' AS ga_equal,                     -- 1
    _utf8mb4'ガ' COLLATE utf8mb4_0900_ai_ci
        LIKE _utf8mb4'ｶﾞ' AS ga_like;                   -- 0
```

実際の登録も確認します。
次のSQLは検証用DBを選択し、1文ずつ実行してください。

```sql
CREATE TEMPORARY TABLE collation_unique_demo (
    value VARCHAR(64)
        CHARACTER SET utf8mb4
        COLLATE utf8mb4_ja_0900_as_cs_ks NOT NULL,
    UNIQUE KEY uq_value (value)
) ENGINE = InnoDB;

INSERT INTO collation_unique_demo VALUES (_utf8mb4'カナ');
INSERT INTO collation_unique_demo VALUES (_utf8mb4'かな');
-- 上の2件は登録できます。

INSERT INTO collation_unique_demo VALUES (_utf8mb4'ｶﾅ');
-- 'カナ' と同等なので、期待結果は重複エラーです。

INSERT INTO collation_unique_demo VALUES (_utf8mb4'商品(赤)');
INSERT INTO collation_unique_demo VALUES (_utf8mb4'商品（赤）');
-- 最後のINSERTも、期待結果は重複エラーです。

SELECT value FROM collation_unique_demo WHERE value = _utf8mb4'かな';
-- 'かな' の1行だけ返ります。

SELECT value FROM collation_unique_demo IGNORE INDEX (uq_value)
    WHERE value LIKE _utf8mb4'かな';
-- 同じ条件でも 'かな' と 'カナ' の2行が返ります。
```

最後の2文が、この記事の中心にある差です。
`ks` はUNIQUEとひらがな・カタカナの区別を保ちながら、`LIKE` にはその区別を伝えません。

実際に受け付ける入力を追加し、濁点付きの半角カタカナ、結合文字、不可視文字、空白の種類も比較します。
検索には `=` だけでなく、実際の `LIKE`、正規表現、全文検索の式を用います。
`LIKE` は索引を使う場合と使わない場合の両方を試します。
実行環境の `VERSION()` とSQLを残しておけば、将来の移行でも比較できます。

## 選定と見直しの順序

照合順序から考え始めるのではなく、登録と検索の具体例から決めます。

- [ ] UNIQUE付きの識別子ごとに、登録できてはいけない組み合わせを挙げる。
- [ ] 別々に登録できるべき組み合わせを挙げる。
- [ ] 濁点、かな、幅、小書き文字を検索でどこまで同一視するか決める。
- [ ] 原文、検索キー、一意判定キーを分ける必要があるか判断する。
- [ ] 採用する変換処理と照合順序で `=`、`LIKE`（索引あり・なしの両方）、2件目の `INSERT`、重複時更新を試す。
- [ ] 既存DBでは移行前後の衝突、分離、索引、ロック、復元を確認する。

照合順序の名前から結論を出すのではなく、実際に受け付ける文字列を二つ並べ、検索で一致してよいか、同時に登録できてよいかを決める。
その判断を `=` と `LIKE` と通常の `INSERT` で確かめるところまでが、照合順序の選定です。

> [!NOTE] 確認範囲
> MySQL 8.4の公式資料・MySQL 8.4.11の公式実装・Unicodeの仕様と照合データ・RFC 4648を参照した
>
> 検証件数は「比較結果を実機で確かめる」の結果表に集約した
>
> `ßs` / `sß` の反例は別途実行した確認であり 公開JSONには含まれていない
>
> `LIKE` はここに挙げた組と式に限って確認した結果であり すべての文字やパターンに一般化できる保証はない
>
> アプリケーション結合試験・実データ移行試験・ロック時間測定・性能測定・MariaDBなどの互換DB試験は未実施
