代表的な面接トピック

バックエンド面接:Unicodeの大文字小文字を区別しないマッチングにPostgreSQL 18のcasefoldをどう活用するか?

バックエンド普通
Offer.cc 編集チーム公開日 更新日

質問

ユーザー識別子でUnicodeの大文字小文字を区別しないマッチングが必要です。lower()、照合順序(collation)、一意性制約を混同することなく、PostgreSQL 18のcasefold()をどのように評価しますか?

プロンプトとコンテキスト

システムは、Unicode Default Caseless Matchingを使用してユーザー入力からユーザー名またはメールアドレスを検索する必要があります。PostgreSQL 18の casefold() の評価、照合順序の選択、インデックスの構築、および既存データのマイグレーションをどのように行うか説明してください。単一の関数呼び出しの言及にとどまらないでください。

面接官が評価するポイント

  • ケースフォールディングが単純な小文字化とは異なり、1文字が複数文字に展開される可能性があることを理解しているか。
  • UTF-8、照合順序プロバイダ、およびデプロイ環境固有の制約を確認しているか。
  • 式インデックス、一意性、正規化、マイグレーション順序を説明できるか。
  • 衝突検出、ロールバック、パフォーマンス検証、およびユーザー向けルールの設計ができるか。

質問すべき明確化のための質問

  1. 要件はUnicode Default Caseless Matchingですか、それともロケール固有のソートルールですか?
  2. これは検索、ログイン照合、または正規化後のグローバルな一意性のためのものですか?
  3. 既存データに「ß」、ギリシャ文字、または結合文字が含まれる可能性はありますか?表示値の変更は許可されますか?
  4. データベースのエンコーディング、照合順序プロバイダ、バージョン、およびオンラインでのインデックス変更ウィンドウは何ですか?

30秒の回答フレームワーク

マッチングと一意性のセマンティクスを確認し、UTF-8およびケースフォールディングをサポートする照合順序を検証します。casefold() は比較用キーを生成すべきであり、表示値を置き換えるべきではありません。一部の文字は展開され、libcプロバイダは lower() のように動作する可能性があります。オフラインでキーを生成して競合を検出した上で、式インデックスまたは保存されたキーの一意性制約を作成し、クエリプランを監視しながら読み取りと書き込みを段階的に移行します。ローンチ前に、代表的な多言語サンプル、インデックス使用状況、長さの変化、およびロールバックをテストする必要があります。

ステップバイステップの詳細解説

1. マッチングと表示の境界を定義する

元の値は比較用キーとは別に保存します。Unicode正規化、空白の削除、またはメール固有のルールも必要かどうかを判断します。casefoldはケースフォールディングのみを処理します。

2. エンコーディングと照合順序の検証

ドキュメントではUTF-8サーバーエンコーディングが要求されています。ケースフォールディングは照合順序に依存します。Unicode照合順序では「ß」が ss にフォールドされる場合がありますが、ケースフォールディングをサポートしないlibcプロバイダでは casefoldlower と等価になります。デプロイ前にターゲット環境で代表的なサンプルを実行してください。

3. インデックスと一意性の設計

検索には casefold(column) の式インデックスを使用できます。一意性については、比較用キーを永続化するかどうか、および過去の競合をどのように解決するかを決定します。結果の長さが変わらないと仮定したり、表示用カラムで同一性を強制したりしないでください。

4. 安全な移行と検証

既存の行をスキャンして等しいフォールド後キーを探し、マージまたは手動解決ルールを定義してから、バックフィルと制約の追加を段階的に行います。EXPLAIN、本番相当の多言語サンプル、同時書き込み、およびリトライを用いて検証します。競合が発生した場合は切り替えを一時停止し、ロールバックスイッチを保持してください。

模範解答

casefold() を表示の変換ではなく、比較用キーのルールとして扱います。Unicode Default Caseless Matching、UTF-8エンコーディング、および「ß」などの文字に対するターゲット照合順序の動作を確認し、サポートされていないlibcフォールディングは lower() にフォールバックするためプロバイダをチェックします。既存の行をスキャンしてフォールド後キーの競合を確認し、保存されたキーまたは式インデックスを選択して、適切な一意性制約を作成します。マイグレーションでは、クエリプラン、並行性、多言語、およびロールバックのテストを行いながら、段階的なバックフィルとデュアルライトを実施します。マッチングルールを明示的に保ちながら、ユーザーには元の値を表示します。

よくある間違い

  • casefold()lower() の単純なエイリアスとして扱うこと。
  • UTF-8、照合順序、およびプロバイダの違いを無視すること。
  • フォールド後の出力が同じ長さを維持すると仮定して切り詰めてしまうこと。
  • 過去の競合をスキャンする前に一意性制約を追加すること。
  • 表示値を比較用キーで上書きすること。
  • 機能のみをテストし、多言語データでの式インデックスのプランをテストしないこと。

フォローアップ質問と回答

casefoldは正規化を代替できますか?

いいえ。ケースフォールディングのみを処理します。結合文字、互換文字、およびビジネス上のクリーンアップには個別の正規化ルールが必要であり、その適用順序をテストする必要があります。

なぜ「ß」が有用なテストケースなのですか?

PG_UNICODE_FAST などの照合順序では、「ß」は ss にフォールドされる場合があります。この長さの変化により、マッチング、フィールドサイズ、および一意性の設計前提を一度に検証できます。

libcプロバイダはどのようなリスクをもたらしますか?

ドキュメントによると、ケースフォールディングがサポートされていない場合、libcは casefoldlower と等価にします。照合順序/プロバイダを固定し、本番相当の環境でマイグレーションおよびリグレッションテストを実行してください。

公開情報ソース

関連する質問