db-keys について
db-keysは、主キーの有無や型、行の識別とインデックス動作への適合性を調べるデータベース監査スキルです。開発者がキー設計のリスクを把握できるよう、静的チェックと実行時の証拠が必要な検証を区別します。
主な機能
- 01識別子のないテーブルやコレクションの検出
- 02UUIDと整数キー戦略の確認
- 03変更される自然キー主キーの検出
- 04複合キーの列順序の確認
- 05静的・実行時検証の案内
活用シーン
- 01スキーマDDLの主キー確認
- 02データベースの証拠に基づくキー枯渇リスク評価
- 03書き込みの多いテーブルのキー選定評価
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ hainrixz/ claude-db --skill db-keysインストール後、Claude Code で/db-keysを入力して読み込まれたか確認します。
詳細
db-keys (M2)
主キーは行のアイデンティティに関する契約です。行の参照方法、ディスク上でのクラスタリング方法、スケーリングの仕方を決定します。主キーがない、または枯渇することは、スコアに上限を設ける数少ない欠陥の一つです。このモジュールは両方の軸を対象とし、設計面ではアイデンティティとモデリング、パフォーマンス面ではインデックスの局所性と枯渇を評価します。
チェック項目
- 主キーがない(またはコレクションに一意な行識別子がない):上限を設けるケースです。主キーのないテーブルは、安全に更新、複製、重複排除できません。
- 主キーの型戦略:クラスタリングキー/B-tree の先頭キーとしてランダムな
UUIDv4を使うと、挿入が分散し、インデックスが肥大化します。時間順のUUIDv7/ULID、またはbigintの ID を推奨します。書き込み頻度の高いテーブルでuuid_generate_v4()をデフォルト値に指定している場合は指摘します。 - Postgres ≥18(2025年9月 GA):ネイティブの
uuidv7()(RFC 9562)は、時間順 UUID の主キーのデフォルトとして推奨されます(uuid_extract_timestamp()でタイムスタンプを復元できます)。検出されたエンジンが PG ≥18 の場合、gen_random_uuid()/v4 のデフォルトは格下げとして扱い、uuidv7()を推奨します。18 より前のバージョン、または Postgres 以外のエンジンでは、gen_random_uuid()とアプリケーション側で生成する UUIDv7 も引き続き適切です。 - 自然キーと代理キー:変更される可能性のある自然キー(メールアドレス、スラッグ)を主キーにすると、すべての FK に変更が波及します。安定した代理キーを推奨します。
- 整数型の幅の枯渇:データ量が約21億行を超える可能性があるテーブルで、
int4/serial/SERIALを主キーに使用している場合です。int4の枯渇は本番環境の稼働を停止させる事象です。安全なデフォルトはbigint/bigserialです。 - 複合主キーの順序:複合主キーでは、先頭の列を主要なアクセス/パーティション分割パターンに合わせます(M9 の tenant_id、M11 の ESR に関連します)。
軸と重大度
- リレーショナルテーブル/ワイドカラムテーブルに主キーがない場合:重大度 5、
fail、軸both、信頼度established(両方のスコアに上限を設けます)。 int4/serial 主キーが枯渇間近の場合:Tier-1 の行数の証拠がある場合に限り重大度 5。それ以外は重大度 4 のwarn、信頼度directional(ライブデータがなければ上限を設けることはありません)。- 書き込み頻度の高いテーブルで
UUIDv4をクラスタリング主キーとして使用している場合:重大度 3、warn、軸performance、信頼度directional。 - 変更される可能性のある自然キーを主キーとしている場合:重大度 3、
warn、軸design。
Tier-0 静的チェック
scripts/parse-schema.mjs で DDL/スナップショットを解析し、すべてのテーブルで PRIMARY KEY(またはドキュメントストアの _id/シャード識別子)が宣言されていることを確認します。主キー列の型を調べ、uuid と gen_random_uuid()/uuid_generate_v4() のデフォルト値、および int4/serial の使用を確認します。プログラムソースの解析結果が方向性を示す場合でも、重大度 5 の「主キーなし」による上限は適用しません。
Tier-1 検証クエリ
主キーのないテーブルを特定します:
-- $DATABASE_URL, read-only
SELECT t.table_schema, t.table_name
FROM information_schema.tables t
LEFT JOIN information_schema.table_constraints c
ON c.table_name = t.table_name AND c.table_schema = t.table_schema
AND c.constraint_type = 'PRIMARY KEY'
WHERE t.table_type = 'BASE TABLE' AND t.table_schema NOT IN ('pg_catalog','information_schema')
AND c.constraint_name IS NULL;
int4 主キーの残り容量を確認します(枯渇による重大度 5 を裏付けます):
SELECT max(id) AS cur, 2147483647 AS int4_max, round(100.0*max(id)/2147483647,1) AS pct_used FROM <table>;
指摘事項
schema/finding.schema.json に従って出力します。例:
M2.events.no_primary_key— ベーステーブルに主キーがありません(重大度 5、fail、軸both、信頼度established)。M2.audit_log.int4_pk_exhaustion—id integerの主キーが int4 の最大値に対して高い割合に達しています(重大度 5 は Tier-1、静的チェックでは 4、軸both)。M2.orders.uuidv4_clustered_pk—gen_random_uuid()をデフォルト値とするランダムなuuid主キーにより、挿入が分散します(重大度 3、warn、軸performance、信頼度directional)。
各指摘事項では、evidence.observed に主キーの DDL またはカタログの結果をそのまま引用します。verification.reproduce には、上記の実行可能なクエリ(method: ddl_parse/schema_introspect/query_stat)を指定します。expected_impact は段階分けし、信頼度タグを付けます。
正確性
- Tier-1 の
max(id)と増加傾向を確認せずに、int4の枯渇が差し迫っていると主張しないでください。静的チェックでは信頼度はdirectionalであり、上限を設けることはありません。 UUIDv4が「誤り」というわけではありません。問題となるのは、書き込み頻度の高いテーブルでの挿入時にインデックスの局所性が低下することです。影響は段階分けして評価し、挿入スループットの割合を捏造しないでください。- 代理キーと自然キーのどちらを選ぶかは状況によります。一方が常に正しいと断言せず、それぞれのトレードオフを示してください。