mcpField
D
db-keys

db-keys

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

关于 db-keys

db-keys 是用于检查主键存在性、类型及其对行标识和索引行为影响的数据库审计技能,帮助开发者发现键设计风险,并区分静态检查与需运行时证据的验证。

主要功能

  1. 01查找缺少标识符的表或集合
  2. 02检查 UUID 和整数键策略
  3. 03标记可变自然键主键
  4. 04检查复合键列顺序
  5. 05提供静态及实时验证指引

适用场景

  1. 01检查架构 DDL 中的主键
  2. 02依据数据库证据评估键耗尽风险
  3. 03评估高写入表的键选择

安装

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

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

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

详细介绍

db-keys (M2)

主键是行的身份契约:它决定行如何被引用、如何在磁盘上聚簇,以及如何扩展。缺少主键或主键即将耗尽,是少数可能拉低评分上限的问题之一。本模块同时涉及两个维度:设计方面的身份建模,以及性能方面的索引局部性和耗尽风险。

检查内容

  • 没有主键(或集合中没有唯一的行标识符):这是会触发上限的情况。没有主键的表无法安全地更新、复制或去重。
  • 主键类型策略:将随机的 UUIDv4 用作聚簇/前导 B-tree 键会导致插入碎片化并使索引膨胀;优先使用按时间排序的 UUIDv7/ULID 或 bigint identity。对高频插入表上的 uuid_generate_v4() 默认值发出警示。
  • Postgres ≥18(2025 年 9 月正式发布):原生 uuidv7()(RFC 9562)是推荐的按时间排序 UUID 主键默认值(可通过 uuid_extract_timestamp() 恢复时间戳)。当检测到引擎为 PG ≥18 时,将 gen_random_uuid()/v4 默认值视为降级,并建议使用 uuidv7()。对于 18 之前的版本或非 Postgres 引擎,gen_random_uuid() 和应用侧生成的 UUIDv7 仍然适用。
  • 自然键与代理键:将可变的自然键(电子邮件、slug)用作主键,会使每个外键都随之变更;建议使用稳定的代理键。
  • 整数位宽耗尽:当表的行数可能超过约 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 上限的较高百分比(Tier-1 时严重性 5 / 静态检查时严重性 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 并非“错误”;其代价是高频插入时索引局部性较差。应对影响范围分级,绝不捏造插入吞吐量百分比。
  • 使用代理键还是自然键取决于具体情境;应说明各自的权衡,不要断言其中一种普遍正确。

评论

支持 Markdown