关于 db-defaults-generated
用于数据库审计的技能,检查默认值、生成列及标识列或序列设置中的正确性风险。它帮助团队判断哪些值应由数据库强制管理,而非由应用代码分别维护。
主要功能
- 01检查时间戳列默认值
- 02识别由应用维护的派生值
- 03标记空字符串和哨兵默认值
- 04审查标识列与序列设置
- 05检查布尔值默认值
适用场景
- 01审计不同写入方的时间戳处理
- 02审查存储的总计值或搜索向量
- 03查找掩盖缺失值的默认值
- 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