mcpField
D
db-defaults-generated

db-defaults-generated

github.com/hainrixz数据与数据库2170 次安装3 天前更新
代码仓库

关于 db-defaults-generated

用于数据库审计的技能,检查默认值、生成列及标识列或序列设置中的正确性风险。它帮助团队判断哪些值应由数据库强制管理,而非由应用代码分别维护。

主要功能

  1. 01检查时间戳列默认值
  2. 02识别由应用维护的派生值
  3. 03标记空字符串和哨兵默认值
  4. 04审查标识列与序列设置
  5. 05检查布尔值默认值

适用场景

  1. 01审计不同写入方的时间戳处理
  2. 02审查存储的总计值或搜索向量
  3. 03查找掩盖缺失值的默认值
  4. 04检查序列归属和标识列选择

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/hainrixz/claude-db --skill db-defaults-generated

安装后在 Claude Code 中输入/db-defaults-generated确认已加载。

详细介绍

db-defaults-generated (M6)

默认值和生成列在源头确保正确性:created_at DEFAULT now() 对每个写入方都有效,而 GENERATED ALWAYS AS 列永远不会偏离其输入值。将此逻辑推到应用端,意味着每个写入方都可能以不同方式出错。本模块属于 design 轴(Tipos 类别)。适用于支持默认值/生成列的引擎。

检查内容

  • 时间戳默认值:created_at/updated_at 仅由应用代码设置(没有 DEFAULT now()/CURRENT_TIMESTAMP,也没有 ON UPDATE/触发器)——不同写入方的行为不一致,直接执行 SQL 插入时可能缺失。
  • 应生成的派生值:由同级列计算得出的存储列(full_name、total = qty*price、search_vector)由应用代码而非 GENERATED ALWAYS AS ... STORED 维护——容易产生漂移(与 M1 的反规范化原则相关)。
  • 非确定性/错误的默认值:将本应动态变化的值固化为默认值;用默认值掩盖缺少 NOT NULL 约束(例如 status DEFAULT 'active' 隐藏了必填意图);或用 DEFAULT '' 代替 NULL。
  • 标识列/序列规范:serial 与 GENERATED ... AS IDENTITY 的选择;序列的所有权共享或配置错误。
  • 缺少布尔值/标志默认值,导致出现原本想避免的三值逻辑。

轴与严重性

  • 轴:design;严重性分级,绝不臆造漂移率。
  • 由应用维护的派生存储列(漂移风险):严重性 3,warn,fixable: proposed。
  • 缺少 created_at/updated_at 数据库默认值:严重性 2–3,warn,fixable: auto(添加默认值,不影响现有数据)。
  • 用 DEFAULT ''/哨兵值掩盖 NULL 语义:严重性 2,warn。
  • M6 不设严重性 5 的上限;它会影响 Tipos 类别的评分值。

Tier-0 静态检查

通过 scripts/parse-schema.mjs 解析 DDL/快照:标记没有 DEFAULT 的 *_at 时间戳列;检测名称暗示其为派生值(full_name、total、*_count、search_vector)但实际上是普通列而非 GENERATED 的存储列;列出默认值为空字符串或哨兵值的情况;指出优先使用 identity 的 serial。对程序源代码的解析结果保持为 directional。

Tier-1 验证查询

检查列默认值和生成状态:

-- $DATABASE_URL, read-only
SELECT table_name, column_name, column_default, is_generated, generation_expression
FROM information_schema.columns
WHERE table_schema NOT IN ('pg_catalog','information_schema')
  AND (column_name ~* '(_at$|total|full_name|count|vector)');

确认「派生」列是否已偏离其输入值:

SELECT count(*) AS drifted FROM order_items WHERE total <> qty * unit_price;

检查结果

按照 schema/finding.schema.json 输出。示例:

  • M6.invoices.total_app_maintained — total 是由应用代码同步的普通列,而非 GENERATED ALWAYS AS ... STORED(严重性 3,warn,轴 design,fixable: proposed)。
  • M6.users.created_at_no_default — created_at 没有 DEFAULT now()(严重性 2,warn,fixable: auto,轴 design)。
  • M6.users.name_default_empty_string — DEFAULT '' 掩盖了 NULL 语义(严重性 2,warn)。 每项检查结果:evidence.observed 引用列 DDL 或默认值原文;verification.reproduce 是上面的可运行查询(method: ddl_parse / schema_introspect / query_stat);expected_impact 按范围分级并标注置信度。

诚实性

  • 数据库默认值不能免除应用对意图的明确表达——仅在数据库侧强制执行明显更安全时才标记(时间戳、派生值),不要一概要求「将所有默认值移到数据库中」。
  • 生成列受引擎/版本支持限制(Postgres 仅支持 STORED,MySQL 支持 VIRTUAL/STORED);建议应限定于检测到的引擎。
  • 如果没有 Tier-1 不匹配计数,绝不要声称派生列已发生漂移;静态检查结果仅为 directional。

评论

支持 Markdown