機微なカラム — SSN、クレジットカード、メール、住所 — はサポート、分析、開発のためにクエリ可能であり続けなければなりません。広範な平文アクセスは答えではありません。データマスキングが答えです。
長年、MySQL の選択肢は 2 つでした。Enterprise の関数ライブラリ、Percona の OSS クローン — いずれもビューで配線します。MySQL 9.7 LTS(2026 年 4 月 21 日)は 3 つ目を加えました。サーバー内のファーストクラスなマスキングポリシーオブジェクトです。合計 4 つの選択肢。本記事で比較します。
MySQL 9.7 Enterprise Dynamic Data Masking
Dynamic Data Masking(DDM)は MySQL 9.7 Enterprise Edition と OCI MySQL HeatWave で GA となりました。ポリシーを定義する。カラムに紐づける。サーバーが強制する。
-- 1. ポリシーを定義する。ゲートキーパーが平文を見られる人を決める。
CREATE MASKING POLICY mask_ssn_policy(ssn_col)
CASE WHEN CURRENT_USER_IN('seeall')
THEN ssn_col
ELSE mask_ssn(ssn_col)
END;
-- 2. ポリシーをカラムに紐づける。
ALTER TABLE protected.user_profiles
ALTER COLUMN ssn
SET MASKING POLICY mask_ssn_policy;
-- 3. 読み取りはすべてポリシーを通る。
SELECT id, first_name, last_name, ssn FROM protected.user_profiles;
-- noseeall → XXX-XX-0001 (マスク済み)
-- seeall → 900-01-0001 (平文)9.7 が提供するゲートキーパーは 2 つ。CURRENT_USER_IN(...) と CURRENT_ROLE_IN(...) です。ポリシー本体は既存の MySQL マスキング関数ライブラリ — mask_inner、mask_outer、mask_pan、mask_ssn、gen_rnd_email、gen_rnd_us_phone — を使います。関数自体は新しくありません。新しいのはポリシー オブジェクト です。9.7 以前は、マスキング関数をカラムに結びつけるにはビューかクエリ内呼び出しが必要でした。9.7 ではサーバーがその結びつけを行います。
ポリシーオブジェクトが追加すること:
- サーバーサイドでの強制。 対話 SQL、アプリケーション通信、
mysqldump、下流の抽出 — どの読み取り経路もマスク済みの値を返します。ベーステーブルへ直接接続してもバイパスできません。 - ビュー一覧が不要。 バリエーション別のビュー目録を 1 つのポリシーが置き換えます。
- 述語安全性。 マスキングは
WHEREやJOINの内側にも適用されます。WHERE ssn LIKE '900-%'というサイドチャネルは塞がれます。
しないこと:
- 行レベルフィルタリング。 DDM はカラムを制御し、行は制御しません。行レベルの制御が必要なら行レベルフィルタリングと併用します。
- Community や Percona のカバー。 Enterprise と HeatWave のみです。
MySQL Enterprise Data Masking Plugin(レガシー)
9.7 以前、Enterprise の唯一の経路は 5.7 以降提供されているデータマスキングプラグインでした。プラグインはマスキング関数(mask_inner、mask_outer、mask_ssn、…)を公開しますが、ポリシーオブジェクトは公開しません。生データを守るには、ベーステーブルをそれらの関数を呼ぶビューで包み、ベーステーブルの代わりにビューへのアクセスを付与します。

このパターンは 8.0 と 8.4 では今も使えます。その制約はよく知られています:
- アカウントモデルが先。 強制は MySQL ロールに紐づきます。多くのインスタンスではユーザーが数名しかいません。プラグインを採用するなら、ポリシーの前にアカウント設計を作り直す必要があります。
- バリエーションごとに 1 ビュー。 バリエーションが増えるたびにビュー一覧が膨らみます。スキーマ変更は一覧全体に波及します。
- 管理面が無い。 素の SQL です。バージョン管理、レビュー、監査は自分で行います。
- ベーステーブル経由でバイパス可能。 ベーステーブルに
SELECTを持つ誰もが平文を見られます。
9.7 Enterprise では、新規の作業についてはポリシーオブジェクトがこのパターンを置き換えます。関数は直接呼び出し用に残ります。
Percona Data Masking Plugin
Percona Data Masking は、レガシーの Enterprise プラグインのオープンソースクローンで、Percona Server for MySQL に同梱されています。

同じ関数ライブラリ。同じビューベースのパターン。同じ制約。無料、ただし Percona Server 限定。9.7 時点で、Percona は CREATE MASKING POLICY を実装していません。OSS の経路は依然として関数の上のビューです。
Bytebase Dynamic Data Masking

Bytebase Dynamic Data Masking はポリシーを Bytebase で定義し、SQL Editor のクエリ結果で強制します。ビュー不要。エンジン別プラグイン不要。あらゆる MySQL ディストリビューションで 1 つのポリシーモデル。ポリシー変更と例外申請は組み込みのワークフロー — 申請。レビュー。承認。 — を通り、すべてのステップが監査されます。
ポリシーは固定の優先順位で評価される 3 つのレイヤーから構成されます: マスキング例外 > グローバルマスキングルール > カラムマスキング。
- グローバルマスキングルール。 ワークスペース単位、iptables のように順序付け — 最初に一致したルールが勝ちます。一致条件は環境、プロジェクト、データベース、データ分類レベルにまたがります。一致するたびに Semantic Type が適用され、その Semantic Type がマスキングアルゴリズム(full、partial、MD5、range、カスタム)を選びます。

- カラムマスキング。 プロジェクト単位のオーバーライド。
Project Ownerがグローバルルールに該当しない特定カラムに Semantic Type を割り当てます。グローバルルールはカラムマスキングに優先します。

- マスキング例外。 指名されたユーザーが特定のデータベースまたはテーブルに対して期限付きの
QueryまたはExport例外を受けます。サービスアカウントは対象外 — 例外は SQL Editor でクエリする人間ユーザー向けです。すべての付与とすべてのアクセスが記録されます。

マスキングは 感染性 があります。カラムがマスクされると、そのポリシーは依存するすべてのビューと派生構造に伝播します。結果は SQL Editor に直接届きます。

ポリシーは GitOps でコード化することもできます。
マスキングの決定は監査ログに記録されます。SQL 実行エントリは、どのカラムがマスクされて返ったか、どの Semantic Type がそれを発火させたか、どのルールが一致したかというカラム単位のマスキングメタデータを、ユーザー、送信元 IP、ステートメント、行数とともに記録します。例外の付与、例外の行使、ポリシーの編集はファーストクラスの監査イベントです。ポリシーと、それが強制された証跡は同じレコードに収まります。
強制の境界: Bytebase は SQL Editor を経由するクエリをマスクします。データベースに直接到達するトラフィックはバイパスします。運用上のパターンは、人間のアクセスを Bytebase 経由に集約することです — それができれば、MySQL Community、Enterprise、Percona、RDS、Aurora、マネージドフォーク全体にマスキングが一様に適用されます。
比較
| MySQL 9.7 Enterprise DDM | Enterprise プラグイン(レガシー) | Percona プラグイン | Bytebase Dynamic Data Masking | |
|---|---|---|---|---|
| 互換性 | MySQL 9.7+ Enterprise、HeatWave | MySQL Enterprise | Percona Server for MySQL | あらゆる MySQL ディストリビューション ⭐️ |
| メカニズム | カラム上のポリシーオブジェクト ⭐️ | 関数 + ビュー | 関数 + ビュー | Bytebase 内のポリシー、SQL Editor で適用 |
| 強制位置 | データベース、全読み取り経路 ⭐️ | ビュー境界 | ビュー境界 | SQL Editor |
| ポリシー管理 | ファーストクラスのサーバーオブジェクト | DIY ビュー | DIY ビュー | 集中 UI、付与、監査ログ ⭐️ |
| ワークフロー | DDL のみ | DDL のみ | DDL のみ | 申請。レビュー。承認。 ⭐️ |
| 行レベル制御 | 無し(行レベル制御と併用) | 無し | 無し | 無し(アクセスポリシーと併用) |
| 価格 | 有償 | 有償 | 無料 ⭐️ | 有償 |
選び方
- 9.7 Enterprise または OCI HeatWave の場合。 ポリシーオブジェクトを使う。
SELECT *、mysqldump、直接クライアントセッションを通じて一様に強制する唯一の選択肢。 - 8.0 / 8.4 Enterprise の場合。 ビュー付きのレガシープラグインを使う。次の LTS アップグレードでポリシーへの移行を計画する。
- Percona Server で Enterprise の予算が無い場合。 Percona プラグインを使う。制約はレガシーの Enterprise プラグインと同じ。
- 複数の MySQL ディストリビューション、または MySQL を Postgres / Snowflake / マネージドフォークと併用するフリートの場合。 Bytebase を使う。1 つのポリシーモデル。すべてのエンジン。すべてのアンマスクに監査付きの付与。
このチュートリアルで Bytebase Dynamic Data Masking を試せます。質問は Discord チャンネルへどうぞ。