db-types-precision について
データベース監査向けのスキルで、金額の精度、タイムゾーンのないタイムスタンプ、JSONに隠れた構造など、型設計のリスクを確認します。リレーショナル型とドキュメント型のスキーマレビューに使えます。
主な機能
- 01浮動小数点の通貨列を検出
- 02タイムゾーンのない日時を確認
- 03JSON内の安定したスキーマを検出
- 04列挙型、文字セット、照合順序を確認
- 05DDLとスキーマスナップショットを解析
活用シーン
- 01通貨列の型をレビュー
- 02タイムスタンプ列を監査
- 03JSON列に隠れたスキーマを確認
- 04MySQLの文字セットと照合順序を調査
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ hainrixz/ claude-db --skill db-types-precisionインストール後、Claude Code で/db-types-precisionを入力して読み込まれたか確認します。
詳細
db-types-precision (M4)
型は最初で最も低コストな制約です。どの値を表現できるか、また値がどのようにソート、比較、丸められるかを決定します。典型的なデータ損失バグである「金額を浮動小数点数で扱う」問題は、ここに該当します。このモジュールは設計軸(M6 と共通の Tipos カテゴリ)です。パラダイムに応じた型の語彙(Postgres の numeric、Mongo の Decimal128)を使って、各パラダイムに適用されます。
チェック内容
- 金額の浮動小数点数での扱い:通貨/金額に
float/real/double precision(または Mongo のDouble)を使用している場合です。二進浮動小数点数では、10 進数のセントを正確に表現できません。numeric/decimal/Decimal128/最小通貨単位の整数を使用してください。これは重大度 5 の上限です。 - タイムスタンプとタイムゾーン:タイムゾーンをまたぐ時点に、タイムゾーンなしの
timestamp/datetimeを使用している場合です。UTC で保存されるtimestamptzを推奨します。タイムゾーンのない*_atという名前のtimestamp列にフラグを付けます。 - スキーマ回避としての jsonb:ファーストクラスの型付き/制約付き列にすべき内容(安定していて、クエリされ、外部キーに関連するキー)が
jsonb/json列に格納されている場合です。柔軟なデータの塊を埋め込むのは問題ありませんが、スキーマを隠すのは問題です。 - enum とルックアップテーブルの比較:参照先のルックアップテーブルのほうが安全に変更できる場面で、ネイティブ
ENUM(特に変更が難しい MySQL のENUM)を使っている場合、または制約付きドメインが必要な場面で自由記述のステータスを使っている場合です。 - 文字セット/照合順序:
utf8mb4ではなく MySQL のutf8(3 バイトで、絵文字/補助平面文字に対応しない)を使っている場合、または識別子/メールアドレスに意図しない大文字小文字を区別する照合順序やアクセントを区別する照合順序が設定されている場合です。
軸と重大度
- 浮動小数点数/double 型の金額:重大度 5、
fail、軸design、信頼度established(Design スコアに上限を設定します)。 - タイムゾーンをまたぐ時点にタイムゾーンなしのタイムスタンプを使用:重大度 3~4、
warn、軸design。 - 安定したクエリ対象のスキーマを隠す jsonb:重大度 3、
warn、fixable: proposed。 - MySQL の
utf8(utf8mb4 ではない):重大度 3、warn。 - enum による変更の固定化/誤った照合順序:重大度 2~3、
warn。
Tier-0 静的チェック
scripts/parse-schema.mjs で DDL/スナップショットを解析します。金額を示す列名(price, amount, total, balance, cost, *_cents)と float|real|double|Double 型の組み合わせを照合します。*_at 列のうち、タイムゾーンなしの timestamp/datetime にフラグを付けます。json/jsonb 列と ENUM(...) を検出し、宣言された文字セット/照合順序を読み取ります。方向性を示すプログラムソースの解析では、金額の浮動小数点数による重大度 5 の上限を引き起こしません。
Tier-1 検証クエリ
カタログから金額を格納する浮動小数点数の列を確認します。
-- $DATABASE_URL, read-only
SELECT table_name, column_name, data_type
FROM information_schema.columns
WHERE data_type IN ('real','double precision')
AND column_name ~* '(price|amount|total|balance|cost|fee|tax)';
MySQL の文字セットを確認します。
SELECT table_name, column_name, character_set_name, collation_name
FROM information_schema.columns WHERE character_set_name = 'utf8';
検出結果
schema/finding.schema.json に従って出力します。例:
M4.orders.total_float_money—total double precisionはセントを失います(重大度 5、fail、軸design、信頼度established)。M4.events.created_at_naive_timestamp—created_at timestampにはタイムゾーンがありません(重大度 4、warn、軸design、fixable: proposed)。M4.products.attributes_jsonb_schema_evasion— 安定したクエリ対象のキーがjsonbに埋もれています(重大度 3、warn)。M4.users.email_utf8_not_utf8mb4— MySQL のutf8は補助平面文字を切り捨てます(重大度 3、warn)。 各検出結果では、evidence.observedに列の DDL をそのまま引用します。verification.reproduceには、上記の実行可能なクエリ(method: ddl_parse/schema_introspect)を指定します。expected_impactは段階分けし、信頼度を付けます。
正確性
- パラダイムにかかわらず、金額を浮動小数点数で扱う場合は上限を適用します(リレーショナル型と Mongo の
Doubleの両方)。決して軽減しないでください。 jsonbは真に柔軟または疎なデータに適したツールです。安定していて、クエリされ、リレーショナルなスキーマを隠している場合に限り、フラグを付けてください。- 宣言された照合順序を示さずに、照合順序が問題を引き起こすと断定しないでください。影響は段階分けし、ソートエラー率を作り上げないでください。