AIエージェントがデータベースを直接読み始めた
MCP(Model Context Protocol)は、AIツールが外部のデータやシステムに接続する方式を一つに揃えようとするオープン標準です。Anthropicが2024年11月25日に公開し、2025年12月9日にLinux Foundation傘下のAgentic AI Foundationに寄贈されました。データベース用のMCPサーバーを接続すると、AIエージェントがテーブル一覧やカラムを照会し、SQLを直接実行できます。
ここで設計の観点に変化が生まれます。人間の開発者は社内Wikiを読んだり同僚に尋ねたりできますが、エージェントが見るのはほとんどがデータベースカタログ — テーブル名、カラム名と型、制約、コメント — です。スキーマそのものがドキュメントになってはじめて、エージェントは見当違いのテーブルを結合したり、単位を取り違えたりせずに済みます。
この記事では、人間にとっても有益で、エージェントにとってはさらに重要な5つの原則をPostgreSQLを基準に整理します。
1. 名前は略さず、意味どおりに
エージェントは usr_amt_cd のような略語を推測して解釈します。推測は外れることがあります。
-- 避けるべき名前:略語、単位なし、意味のないフラグ
CREATE TABLE ord (
id BIGINT PRIMARY KEY,
usr BIGINT,
amt NUMERIC,
flg CHAR(1),
dt TIMESTAMP
);
-- 推奨:意味・単位・タイムゾーンが名前と型に表れる
CREATE TABLE orders (
id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
customer_id BIGINT NOT NULL,
amount_krw NUMERIC(12,0) NOT NULL,
is_refunded BOOLEAN NOT NULL DEFAULT false,
ordered_at TIMESTAMPTZ NOT NULL DEFAULT now()
);
- 単位と通貨を名前に:
amount_krw、duration_ms、weight_g - ブール値は
is_・has_で:flgの代わりにis_refunded - 同じ概念はすべてのテーブルで同じ名前に:あるところでは
user_id、別のところではmember_noだと、エージェントは両者が同じものかどうか判断できません - 時刻は
TIMESTAMPTZで:タイムゾーンのない値は、人間もエージェントも解釈が分かれます
2. COMMENT ONで意味をカタログに残す
PostgreSQLの COMMENT ON は、説明をカタログ(pg_description)に保存します。コードコメントやWikiと違ってデータベースに付いて回るため、スキーマを照会するツールであれば同じ経路で一緒に読み取れます。
COMMENT ON TABLE orders IS '顧客の注文。決済完了時点で作成され、キャンセルしても行を削除しない(is_refundedで示す)。';
COMMENT ON COLUMN orders.amount_krw IS '決済金額(ウォン、付加価値税込み)。割引適用後の金額。';
COMMENT ON COLUMN orders.is_refunded IS '全額返金の有無。部分返金はrefundsテーブルを参照。';
保存された説明は次のように照会します。
SELECT a.attname AS column_name,
format_type(a.atttypid, a.atttypmod) AS data_type,
col_description(a.attrelid, a.attnum) AS description
FROM pg_attribute a
WHERE a.attrelid = 'orders'::regclass
AND a.attnum > 0
AND NOT a.attisdropped;
何を書いておけばよいでしょうか?
- 値の単位・含まれる範囲(付加価値税を含むかどうか、割引の前か後か)
- ステータス値の意味と遷移ルール
- **論理削除(ソフトデリート)**の有無と「実際に有効な行」の条件
- 他のテーブルとの関係で注意すべき点(部分返金は別のテーブル、など)
3. ルールは制約で — エージェントはアプリケーションコードを見られない
「このカラムは pending、paid、shipped のいずれか」というルールがアプリケーションコードにしかなければ、エージェントにとっては存在しないルールです。制約として宣言すればカタログから読み取れますし、誤った値を書き込もうとしてもデータベースが拒否する最後の防衛線になります。
CREATE TABLE customers (
id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
email TEXT NOT NULL UNIQUE
);
CREATE TABLE shipments (
id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
order_id BIGINT NOT NULL REFERENCES orders (id),
status TEXT NOT NULL
CHECK (status IN ('pending', 'paid', 'shipped', 'delivered')),
shipped_at TIMESTAMPTZ,
CHECK (status <> 'shipped' OR shipped_at IS NOT NULL)
);
- 外部キーを明示すれば、エージェントは結合経路を推測せず、カタログで確認できます
- CHECK は許容される値とカラム間のルールを明らかにします
- NOT NULL・UNIQUE は「必ず存在する」「一つしかない」という事実を伝えます
4. エージェントに見せる面をビューで整理する
「月間売上」をエージェントに毎回元のテーブルから計算させると、質問のたびに返金を含めるかどうかやタイムゾーンの扱いが変わる可能性があります。合意した定義を一つのビューに固定して説明を付けておけば、エージェントはそのビューを使うだけで済みます。
CREATE VIEW monthly_revenue AS
SELECT date_trunc('month', ordered_at AT TIME ZONE 'Asia/Seoul') AS month_kst,
sum(amount_krw) AS revenue_krw,
count(*) AS order_count
FROM orders
WHERE NOT is_refunded
GROUP BY 1;
COMMENT ON VIEW monthly_revenue IS '月間売上(ウォン)。韓国時間基準の月、全額返金された注文を除く。';
5. 権限は最小に — 境界はGRANT、それ以外は補助手段
エージェント用のアカウントは別のロールとして作成し、必要なスキーマの読み取り権限だけを付与します。
CREATE ROLE ai_reader LOGIN; -- パスワード・認証方式は運用環境のポリシーに従って設定
GRANT USAGE ON SCHEMA analytics TO ai_reader;
GRANT SELECT ON ALL TABLES IN SCHEMA analytics TO ai_reader;
ALTER DEFAULT PRIVILEGES IN SCHEMA analytics GRANT SELECT ON TABLES TO ai_reader;
-- ミス防止用のデフォルト値(セキュリティ境界ではない)
ALTER ROLE ai_reader SET default_transaction_read_only = on;
ALTER ROLE ai_reader SET statement_timeout = '15s';
注意点があります。default_transaction_read_only と statement_timeout は、セッション内でユーザーが変更し直せる設定です。誤って書き込みクエリを投げたり、重いクエリが長時間走り続けたりするのを減らしてはくれますが、防いでくれるわけではありません。実際の境界は GRANT で付与した権限です。
- 個人情報のカラムは、エージェント用スキーマのビューから最初から外しておくほうが安全です
- 行単位で範囲を分ける必要があるなら、
ALTER TABLE ... ENABLE ROW LEVEL SECURITYとポリシー(CREATE POLICY)を使います - 本番のプライマリではなく読み取り用のレプリカ(スタンバイ)に接続すれば、重い分析クエリがサービスに与える影響を減らせます
Erdmatesで設計する
Erdmatesでテーブルやカラムに説明を書いておくと、PostgreSQLのDDLとしてエクスポートする際に COMMENT ON TABLE・COMMENT ON COLUMN 文として一緒に出力されます(MySQLの場合はテーブルの COMMENT)。逆に、既存のデータベースのSQLをインポートするときも COMMENT ON 文を読み取り、ERDの説明として復元します。ERDで外部キーの関係を線で確認しながら名前と説明を整えておけば、人間とエージェントが同じドキュメントを見ることになります。
まとめ
エージェントがデータベースを直接扱う時代のスキーマ設計は、新しい技術ではなく、昔からある原則をより厳格に守ることです。意味が伝わる名前、カタログに残る説明、制約として宣言されたルール、合意された定義を収めたビュー、そして最小権限。この5つを備えたスキーマはエージェントの間違いを減らし、たとえ間違えてもデータベースが食い止めてくれます。