ふりがなカラムの照合順序に関するメモ

公開

サイトの設計次第でしょうけれども、PowerCMS Xで構築しているサイトのふりがなカラムを「utf8mb4_unicode_ci」等、濁点・半濁点を区別しないものにしたくなりましたのでメモしておきます。

50音でふりがなの頭文字を検索する時

50音をループし、_beginningモディファイアでふりがなカラムの先頭の文字を検索するように実装しました。

<mt:setvarblock name="kana_list">あ,い,う,え,お,か,き,く,け,こ,さ,し,す,せ,そ,た,ち,つ,て,と,な,に,ぬ,ね,の,は,ひ,ふ,へ,ほ,ま,み,む,め,も,や,ゆ,よ,ら,り,る,れ,ろ,わ</mt:setvarblock>
<mt:var name="kana_list" split="," setvar="kana_list" />
<mt:loop name="kana_list">
  <h2 id="kana<mt:var name="__counter__" escape />"><mt:var name="__value__" escape /></h2>
  <mt:eventnames _beginning="$__value__">
    <!-- かなが$__value__の値ではじまるイベントの情報 -->
  </mt:eventnames>
</mt:loop>

_beginningモディファイアの実装は以下のようになっており、$beginning_kanaに50音が入ってきて$termsにセットします。

$terms['kana'] = ['like' => $app->db->escape_like( $beginning_kana, false, true )];

この時、「utf8mb4_general_ci」のように濁点・半濁点を区別する照合順序だと「か」で検索した時に「が」で始まるオブジェクトは含まれません。「utf8mb4_unicode_ci」の場合は「が」で始まるオブジェクトも含まれます。今回は「が」で始まるオブジェクトも含まれて欲しかったので、濁点・半濁点を区別しない照合順序の方がコードがシンプルになります。また、COLLATE句で照合順序を変更する場合とカラムのインデックスが使われないため、約800件のデータを検索した場合はCOLLATE句を使用しない場合に比べて約8倍遅くなりました。(とはいえ、0.0058秒のようなレベルです。)

ふりがなでソートする時

以下のようにsort_byを利用してふりがなカラムでソートするように設定しました。

<mt:eventnames _beginning="$__value__" sort_by="kana" sort_order="ascend">
  <!-- かなが$__value__の値ではじまるイベントの情報 -->
</mt:eventnames>

この時、「utf8mb4_general_ci」のように濁点・半濁点を区別する照合順序だと、「か」から始まるオブジェクトが全て出力された後に「が」から始まるオブジェクトが出力されます。例えば、

  • 海外安全(かいがいあんぜん)
  • 河川と水害(かせんとすいがい)
  • 外交(がいこう)

となります。

「utf8mb4_unicode_ci」のように濁点・半濁点を区別しない照合順序の方が自然な並び順に感じます。例えば、

  • 海外安全(かいがいあんぜん)
  • 外交(がいこう)
  • 河川と水害(かせんとすいがい)

となります。

まとめ

照合順序に「utf8mb4_general_ci」を使うことが多い印象がありますが、検索結果やソート順が変化するので慎重に選択する必要があることが分かりました。

なお、ふりがなカラムだけ照合順序を変更する場合、モデルJSONに照合順序は含まれないので本番環境・開発環境が分かれている場合は注意が必要です。