代表的な面接トピック

データエンジニアリング面接:MySQLの不可視カラム(Invisible Columns)を安全なスキーマ進化にどう活用するか?

データ普通
Offer.cc 編集チーム公開日 更新日

質問

新しいフィールドを必要とするMySQLテーブルに対して、古いサービスがSELECT *を多用しています。不可視カラムが互換性リスクをどのように軽減するか、また書き込み、インデックス、バックアップ、レプリケーションをどのように検証するかを説明してください。

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

古いクライアントがSELECT *と結果の位置(インデックス)ベースのデコードに依存している一方で、新しいサービスは追加のフィールドを必要としています。明示的な参照、書き込み時のデフォルト値、インデックス、バックアップ、ロールバック境界を含め、MySQL 8.4のINVISIBLEカラムによって古いクライアントと新しいクライアントをどのように共存させられるかを説明してください。

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

  • 不可視性(invisibility)が暗黙的なカラム展開を変更するものであり、ストレージや制約への関与を変更するものではないことを理解しているか。
  • SELECT *、明示的なリスト、INSERTリスト、CREATE TABLE ... SELECTの違いを区別できているか。
  • 主キーおよび一意キー、外部キー、CHECK制約、バイナリログ、バックアップのリストアを考慮しているか。
  • 段階的なロールアウト、可観測性(オブザーバビリティ)、そして最終的なVISIBLEクエリへの移行を計画できるか。

確認すべき明確化の質問

MySQLのバージョン、ストレージエンジン、レプリケーショントポロジ、バックアップツール、そして古いクライアントが本当に位置ベースでデコードしているかを確認します。新しいフィールドにデフォルト値が必要か、一意制約に関与するか、レポートやCDCによって消費されるか、そしてロールバック時にデータを保持したまま存続させる必要があるかを尋ねます。

30秒の回答

不可視カラムはテーブルの一部として存在し続けますが、SELECT *およびtbl.*からは除外されます。明示的な参照を行えば読み書きが可能です。古いクライアントの結果形式が安定したまま維持されるよう、フィールドをINVISIBLEとして追加し、新しいクライアントは読み取りとバックフィルに明示的なカラムリストを使用します。デフォルト値、一意インデックス、外部キー、CDC、バックアップのリストア、CREATE TABLE ... SELECTの可視性をテストします。すべてのコンシューマーの移行が完了した後、可視性をVISIBLEに変更します。これは互換性のためのツールであり、認可やデータの分離を目的としたものではありません。

ステップごとの詳細解説

1. 不可視カラムのセマンティクスを確認する

MySQL 8.4では、明示的に名前を指定しない限り、不可視カラムはSELECT *tbl.*、およびTABLEの結果に含まれません。ストレージ、インデックス、制約を隠蔽するものではなく、カラムレベルのアクセス制御でもありません。

2. 互換性のあるDDLを設計する

ALTER TABLE ... ADD COLUMN ... INVISIBLEを使用し、古い書き込みに対して安全なデフォルト値またはNULLの挙動を選択します。少なくとも1つの可視カラムを維持してください。新しいクライアントは、*の規約を継続するのではなく、明示的なリストを使用し始める必要があります。

3. 読み取り、書き込み、および制約を検証する

古いクライアントは元のカラムセットを受け取る必要があります。新しいクライアントはフィールドを明示的に読み書きします。省略された不可視カラムには、MySQLの暗黙的なデフォルト挙動が適用されます。主キー、一意キー、外部キー、CHECK制約は引き続き適用されるため、重複、カスケード、失敗したトランザクションをテストします。

4. レプリケーションとパイプラインを考慮する

不可視カラムは、行イベントにおいて可視カラムと同様に扱われます。その含まれ方はbinlog_row_imageなどの設定に依存します。SELECT *からレプリケーションを推測するのではなく、実際のカラムリストを使用してCDC、ETL、ORMマッピング、およびデータ品質チェックをテストします。

5. 最小限のマイグレーションスクリプトを作成する

sql
ALTER TABLE orders
  ADD COLUMN risk_score DECIMAL(5, 2) NULL INVISIBLE;

SELECT order_id, status, risk_score
FROM orders
WHERE order_id = ?;

ALTER TABLE orders
  MODIFY COLUMN risk_score DECIMAL(5, 2) NULL VISIBLE;

まずDDLを実行し、明示的な読み取りとバックフィルをデプロイし、古いクライアントのエラーとCDCの遅延を監視した上で、初めて可視性を切り替えます。本番環境の計画では、ロック、オンラインDDLのサポート、ロールバックウィンドウも評価する必要があります。

6. バックアップ、テーブル作成、リストアを確認する

mysqldumpおよびSHOW CREATE TABLEは不可視性のメタデータを保持します。この機能をサポートしていない古いサーバーにリストアすると、バージョンコメントが無視されるため、カラムが可視化される可能性があります。CREATE TABLE ... SELECT内の明示的な不可視カラムは、定義がINVISIBLEを繰り返さない限り、ターゲットで可視化される可能性があります。

質の高い模範解答

私は不可視カラムをセキュリティ境界ではなく、互換性ツールとして扱います。まず、古いクライアントが実際にSELECT *に依存していることを確認し、オンラインDDLパスを介してNULL許容または安全なデフォルト値のセマンティクスを持つINVISIBLEカラムを追加します。古いクライアントは元の結果形式を維持し、新しいクライアントは読み取り、バックフィル、書き込みに明示的なリストを使用する必要があります。テストでは、デフォルト値、明示的な更新、主キーおよび一意キーの競合、外部キーとCHECK制約、ORMマッピング、binlog_row_image下でのCDCの挙動、バックアップのリストア、CREATE TABLE ... SELECTの可視性をカバーします。マイグレーション中は、エラー率、レプリケーション遅延、データ整合性を監視します。すべてのコンシューマーが安定した明示的規約を使用するようになった後、フィールドをVISIBLEに切り替えます。ロールバックではカラムとデータを保持したままアプリケーションバージョンを復元でき、クロスバージョンリストアにはサポート状況とダンプメタデータの確認が必要です。長期的には、結果規約が明示的になるようSELECT *を排除します。

よくある間違い

  • 不可視カラムがキー、CHECK制約、外部キー、バイナリログに関与しないと思い込むこと。
  • SELECT *のみをテストし、明示的な読み取り、書き込み、ORMマッピングをスキップすること。
  • 不可視性をカラムのパーミッション、プライバシー、またはデータ分離として扱うこと。
  • CREATE TABLE ... SELECT、ダンプのリストア、古いサーバーの挙動を無視すること。
  • 新しいクライアントでSELECT *を使い続け、後で互換性の問題を再発させること。

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

不可視カラムはすべてのSELECT *互換性問題を解決しますか?

いいえ。返される結果セットは安定しますが、位置ベースのデコード、ORMリフレクション、レポート、CDCは依然として個別の検証が必要です。長期的な解決策は明示的なカラムリストを使用することです。

不可視カラムを省略してINSERTした場合、何が起こりますか?

MySQLの暗黙的なデフォルト挙動が適用されます。特定の値を書き込むには、カラムを明示的に指定し、NOT NULL、一意制約、CHECK制約をテストします。

いつVISIBLEに戻すべきですか?

読み取り、書き込み、CDC、バックアップ、レポートのすべてが安定した明示的規約を使用し、監視およびロールバック訓練に合格した後に戻します。その後、段階的なロールアウトで可視性を変更します。

公開情報ソース

関連する質問