メインコンテンツへスキップ

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

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

(更新日:)52分で読めます
MySQL照合順序を検索とUNIQUE制約で選ぶ全角・半角の実例

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件目両方登録できるか理由
Cafecaféできない大文字小文字とアクセントを区別しない
商品(赤)商品(赤)できない括弧の幅を区別しない
カナカナできないカタカナの幅を区別しない
かなカナできないひらがなとカタカナを区別しない
はばできない濁点を区別しない
つっできない小書き文字を区別しない
ABCABC (末尾に半角スペース)できる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の説明とutf8mb4の説明で確認できます。

カラムが utf8mb4 でも、アプリケーションとの接続が対応していなければ、文字の受け渡しで問題が起きます。 DBの定義と接続文字セットの両方を確認します。 実機確認では、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を参照し、実際に利用できる名前は SHOW COLLATION で確認します。

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

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

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

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

idname
1ガイドブック
2ガイドブック
3カナ手帳
4カナ手帳
5Café Latte
6(株)東
7㈱東
8ABC (末尾に半角スペース)
9ABC
検索条件一致した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 / cafecafe / 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照合の比較レベル、UnicodeのUCA 9.0.0照合データ、MySQL 8.4.11ソースの日本語向け照合データから導き、後述の実機検証と照合した値です。

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

utf8mb4_0900_ai_ci

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

utf8mb4_0900_as_ci

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

utf8mb4_0900_as_cs

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

utf8mb4_ja_0900_as_cs

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

商品(赤) と 商品(赤)、ABC123 と 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とHiraganaで確認できます。

濁点付きの入力では、ガ・半角の ガ・カ と結合濁点 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_binUNIQUE付きで両方登録できるか
AbC123 と abc123異なるできる
ABC と ABC異なるできる
カナ と カナ異なるできる
ABC と ABC (末尾に半角スペース)異なるできる
同じUTF-8文字列同じできない

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

_bin 系の比較方法を、別の文字セットへそのまま一般化することはできません。 ここで扱う utf8mb4_0900_bin はUTF-8の符号化バイトを重みに使い、utf8mb4_bin と同じ文字の並び順になります。 バイナリ型との違いはMySQL公式のbinary照合と_bin照合の説明で確認できます。

ログイン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も参照します。

メールアドレス

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

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

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

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

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

生のバイト列と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で確認できます。

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

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

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

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

条件utf8mb4_binutf8mb4_0900_bin
PAD属性PAD SPACENO 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で確認できます。

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

Unicode正規化と文字列の長さ

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

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

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

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

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

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

1 / ① と I / Ⅰ はそれぞれ1文字同士の一次重みが一致するため LIKE でも一致する ㈱・№・fi は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を参照します。

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とPRIMARY KEY and UNIQUE Constraintsで確認できます。

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

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

例えばコードが ai_ci のUNIQUEで、既に ABC があるとき、abc を重複時更新付きで送ると、ABC の既存行が更新対象になります。 別のコードのつもりで送ったデータを、既存行へ反映する危険があります。 動作の詳細はMySQL公式のINSERTとINSERT ... ON DUPLICATE KEY UPDATEを参照します。

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

検索式と並べ替え

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

処理確認すること
=照合上の等価判定
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の照合データでは ß の一次重みが s 二つに対応するため 文字列全体では両辺とも sss と同等になる 一方 LIKE が最初に比較するのは ß と s なので一致しない ワイルドカードのないパターンでは 長さに加えて対応する各位置が LIKE の文字比較で一致する必要がある これはMySQL公式の文字単位のLIKE比較の説明とも整合する

ks のかな区別が LIKE に現れないのは、MySQL 8.4.11の実装によるものです。 UCA 9.0.0の重みテーブルは1照合要素あたり3重みを持ち utf8mb4_ja_0900_as_cs_ks の levels_for_compare は4に設定されている

かなの四次重みは走査時に uca_scanner_900::handle_ja_common_quat_wt()が生成する

LIKE の文字比較は my_wildcmp_uca_impl() から my_uca_charcmp() を経由し UCA 9.0では my_uca_charcmp_900()で1コードポイントずつ比較する

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

参照した strings/ctype-uca.cc と strings/uca900_data.h は 公式タグ mysql-8.4.11が指すコミット 99960bf74fa919347e4f4e3ca47672f333d6e91f に固定している

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

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

組照合順序=LIKE理由
ガ / ガutf8mb4_0900_ai_ci同等一致しない1コードポイント対2コードポイント
ß / ssutf8mb4_0900_ai_ci同等一致しない1文字が2文字に展開される
(株) / ㈱utf8mb4_0900_ai_ci同等一致しない3文字が1文字に対応する
1 / ①utf8mb4_0900_ai_ci同等一致する1文字同士の一次重みが一致する
ab / a+U+200B+butf8mb4_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で確認できます。

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

並べ替えで同じ重みになる値について、行の順番が一意に決まるとは限りません。 ページングなどで順番を安定させるなら、ORDER BY name, id のように一意なキーを補助条件にします。 同順位の順序はMySQL公式のLIMIT Query Optimizationも参照します。

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

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

選んだ照合順序は、カラム定義だけでは評価できません。既存データ、索引、移行時の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で確認できます。

既存のgeneral系とunicode系

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

照合順序文字セットと世代保存できる範囲代表的な比較
utf8mb3_general_ciutf8mb3の古いgeneral系4バイトUTF-8文字を保存できないß = s
utf8mb4_general_ciutf8mb4の簡易的なgeneral系4バイトUTF-8文字も保存できるß = s
utf8mb4_unicode_ciUCA 4.0同上ß = ss
utf8mb4_unicode_520_ciUCA 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_ciutf8mb4_unicode_ciutf8mb4_0900_ai_ci
かな / カナ異なる同等同等
カナ / カナ異なる同等同等
は / ば異なる同等同等
つ / っ異なる同等同等
() / ()異なる同等同等
ABC123 / 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で確認できます。

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

性能とインデックス

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

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

検索時にカラムへ関数や別の照合順序を適用すると、既存インデックスで同じように絞り込めるとは限りません。 COLLATE を付ければ常にインデックスが使えなくなる、と断定するのも不正確です。 MySQLのインデックス利用とRange Optimizationを踏まえ、EXPLAIN で確認します。

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

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

既存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で実際に起きた事例を別記事にまとめています。 製品は異なりますが、所要時間とロックの影響を移行前に見積もる観点は共通です。

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とColumn Character Set Conversionを参照します。

文字列の外部キーと参照先には、同じ文字セットと照合順序が必要です。 通常のJOINでも、同じ意味のキー同士は揃えます。 照合順序が混在した比較は、優先順位に従って処理されたり、Illegal mix of collations エラーになったりします。 比較時の優先順位はCollation Coercibility、外部キーの要件はFOREIGN KEY Constraintsで確認できます。

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

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

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

EXPANDABLE CODE比較SQL本文の比較表35セルと追加例を一括で再確認するSQLです。
sql · 135 lines
-- 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'AB12', 1, _utf8mb4'ab12' COLLATE utf8mb4_0900_ai_ci = _utf8mb4'AB12', HEX(_utf8mb4'ab12'), HEX(_utf8mb4'AB12')),
    ('additional', 'utf8mb4_0900_bin', 'hex-alnum-width', _utf8mb4'ab12', _utf8mb4'AB12', 0, _utf8mb4'ab12' COLLATE utf8mb4_0900_bin = _utf8mb4'AB12', HEX(_utf8mb4'ab12'), HEX(_utf8mb4'AB12')),
    ('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'ABC123', 0, _utf8mb4'ABC123' COLLATE utf8mb4_general_ci = _utf8mb4'ABC123', HEX(_utf8mb4'ABC123'), HEX(_utf8mb4'ABC123')),
    ('additional', 'utf8mb4_unicode_ci', 'alnum-width', _utf8mb4'ABC123', _utf8mb4'ABC123', 1, _utf8mb4'ABC123' COLLATE utf8mb4_unicode_ci = _utf8mb4'ABC123', HEX(_utf8mb4'ABC123'), HEX(_utf8mb4'ABC123'));

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;
EXPANDABLE CODEUNIQUE確認SQL各組を空の一時テーブルへ通常INSERTし、重複判定と保存HEXを確認するSQLです。
sql · 299 lines
-- 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'AB12', 1),
    ('additional', 'utf8mb4_0900_bin', 'hex-alnum-width', _utf8mb4'ab12', _utf8mb4'AB12', 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'ABC123', 0),
    ('additional', 'utf8mb4_unicode_ci', 'alnum-width', _utf8mb4'ABC123', _utf8mb4'ABC123', 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;
EXPANDABLE CODELIKE確認SQL完全一致・逆方向・前方一致・部分一致・ワイルドカード・索引有無まで確認するSQLです。
sql · 1157 lines
-- 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'fi', 1, 0,
        _utf8mb4'fi' COLLATE utf8mb4_0900_ai_ci = _utf8mb4'fi',
        _utf8mb4'fi' COLLATE utf8mb4_0900_ai_ci LIKE _utf8mb4'fi',
        _utf8mb4'fi' COLLATE utf8mb4_0900_ai_ci LIKE _utf8mb4'fi',
        CONCAT(_utf8mb4'fi', _utf8mb4'zz') COLLATE utf8mb4_0900_ai_ci LIKE CONCAT(_utf8mb4'fi', _utf8mb4'%'),
        CONCAT(_utf8mb4'zz', _utf8mb4'fi', _utf8mb4'zz') COLLATE utf8mb4_0900_ai_ci LIKE CONCAT(_utf8mb4'%', _utf8mb4'fi', _utf8mb4'%'),
        HEX(_utf8mb4'fi'), HEX(_utf8mb4'fi')),
    ('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'ABC123', 1, 1,
        _utf8mb4'ABC123' COLLATE utf8mb4_0900_ai_ci = _utf8mb4'ABC123',
        _utf8mb4'ABC123' COLLATE utf8mb4_0900_ai_ci LIKE _utf8mb4'ABC123',
        _utf8mb4'ABC123' COLLATE utf8mb4_0900_ai_ci LIKE _utf8mb4'ABC123',
        CONCAT(_utf8mb4'ABC123', _utf8mb4'zz') COLLATE utf8mb4_0900_ai_ci LIKE CONCAT(_utf8mb4'ABC123', _utf8mb4'%'),
        CONCAT(_utf8mb4'zz', _utf8mb4'ABC123', _utf8mb4'zz') COLLATE utf8mb4_0900_ai_ci LIKE CONCAT(_utf8mb4'%', _utf8mb4'ABC123', _utf8mb4'%'),
        HEX(_utf8mb4'ABC123'), HEX(_utf8mb4'ABC123')),
    ('additional', 'utf8mb4_ja_0900_as_cs', 'alnum-width', _utf8mb4'ABC123', _utf8mb4'ABC123', 1, 1,
        _utf8mb4'ABC123' COLLATE utf8mb4_ja_0900_as_cs = _utf8mb4'ABC123',
        _utf8mb4'ABC123' COLLATE utf8mb4_ja_0900_as_cs LIKE _utf8mb4'ABC123',
        _utf8mb4'ABC123' COLLATE utf8mb4_ja_0900_as_cs LIKE _utf8mb4'ABC123',
        CONCAT(_utf8mb4'ABC123', _utf8mb4'zz') COLLATE utf8mb4_ja_0900_as_cs LIKE CONCAT(_utf8mb4'ABC123', _utf8mb4'%'),
        CONCAT(_utf8mb4'zz', _utf8mb4'ABC123', _utf8mb4'zz') COLLATE utf8mb4_ja_0900_as_cs LIKE CONCAT(_utf8mb4'%', _utf8mb4'ABC123', _utf8mb4'%'),
        HEX(_utf8mb4'ABC123'), HEX(_utf8mb4'ABC123')),
    ('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・途中終了を別の処理で判定してください。

実行条件と各ケースの実測値は公開検証結果から確認できる 以下の条件と件数は この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 で確かめるところまでが、照合順序の選定です。

Written by

柿添貴士(TakashiKakizoe) profile photo

柿添貴士(TakashiKakizoe)

Webエンジニア/テックリード

Fukuoka, Japan

  • PHP
  • Laravel
  • Next.js
  • AWS
  • Cloudflare
  • AI Agent