首页 › tutorials › 造建表Skill:需求秒出DDL

概述

本教程带你从零开发一个 Claude Code 自定义 Skill——"schema-designer"。它接收一句自然语言需求(如"做一个多租户博客系统"),自动产出符合范式的建表 DDL、索引、外键和种子数据 SQL。学完后你将掌握 Skill 的目录结构、frontmatter 配置、渐进式加载、动态上下文注入、参数替换与 evals 评估闭环,具备独立设计任意 Skill 的能力。适合已装好 Claude Code、想把自己的重复工作流沉淀为可复用工具的开发者。

前置条件

一、先弄懂 Skill 到底是什么

很多教程一上来就让你写文件,但理解机制比照抄更重要。Claude Code 的 Skill 本质是一个文件夹,里面至少有一个 SKILL.md。它和你塞进 CLAUDE.md 的内容有本质区别:

维度 CLAUDE.md Skill
加载时机 每轮对话全量常驻 仅描述常驻,正文用时才加载
Token 成本 持续消耗 不用几乎为零
触发方式 永远在 描述命中或 /skill-name
适合放什么 事实、规矩、偏好 多步骤流程、清单、可复用套路

这就是官方反复强调的渐进式加载(progressive disclosure):Claude 只把每个 Skill 的 description(连同 when_to_use,合计上限 1536 字符)塞进技能清单里。真正那份几百行的正文,只有 Claude 判断"这次用得上"或你手动 /schema-designer 时才整体读入。所以你可以放心地写一个详尽的参考文档,平时一点也不浪费。

记住这条铁律:当你发现自己反复粘贴同一段指令、同一个清单、同一套步骤时,就该把它抽成 Skill。

二、设计:先想清楚再动手

写代码前先回答四个问题,能避免 90% 的返工:

  1. 触发方式:让 Claude 自动触发,还是只允许手动 / 调用?建表这种需要人工拍板的场景,建议设 disable-model-invocation: false 允许自动,但保留手动入口。
  2. 输入是什么:一句话需求?已有 ER 图?本次输入是"自然语言需求 + 可选的方言(mysql/postgres)"。
  3. 输出是什么:可执行的 DDL,带注释、索引、外键、种子数据。
  4. 要不要支撑文件:命名规范、索引规则这种长参考,应拆成独立文件,而不是堆进 SKILL.md。官方建议正文控制在 500 行以内。

本例最终目录结构:

~/.claude/skills/schema-designer/
├── SKILL.md            # 入口:总览 + 流程 + 导航
├── conventions.md      # 命名与范式规范(按需加载)
└── templates/
    └── ddl.template.sql  # DDL 骨架模板

三、创建目录与 SKILL.md

Skill 存放位置决定作用域,务必先选对:

我们选个人级,让它在任何后端项目都能用:

mkdir -p ~/.claude/skills/schema-designer/templates
cd ~/.claude/skills/schema-designer

接着新建 SKILL.md。每个 Skill 由两段构成:--- 之间的 YAML frontmatter(告诉 Claude 何时用),和后面的 Markdown 正文(告诉 Claude 怎么做)。目录名决定命令名,所以你在 / 菜单里输入的会是 /schema-designer。

---
name: schema-designer
description: 把自然语言需求转成规范的建表 DDL(含索引、外键、种子数据)。用于用户描述业务、要设计数据库表结构、要生成 CREATE TABLE 语句时。
when_to_use: |
  触发词:设计表、建表、数据库 schema、数据建模、CREATE TABLE、
  多对多怎么建表、要不要加索引、生成建表 SQL。
argument-hint: [需求描述] [数据库方言]
arguments: [requirement, dialect]
allowed-tools: Read Write Glob Bash
---

# Schema Designer

你是一位资深数据架构师。根据用户的需求产出可直接执行的建表脚本。

## 输入

- 需求:$requirement
- 方言:$dialect(缺省为 mysql,可选 postgres)

## 工作流程

1. 读取已有 schema 作为约束
   当前项目若已有迁移文件,先扫描:
   !`find ${CLAUDE_PROJECT_DIR} -type d \( -name migrations -o -name db \) 2>/dev/null | head`

2. 拆解实体:从需求中识别名词,列出候选实体与关系。

3. 规范化:遵循 conventions.md 中的命名与范式规则(需要时读取)。

4. 产出 DDL:按 templates/ddl.template.sql 的结构生成,包含:
   - 表注释(中文说明该表用途)
   - 字段(统一 id/timestamps 软删除约定)
   - 主键、唯一键、外键、业务索引
   - 种子数据 INSERT(至少 3 行示例)

5. 自检清单(逐条核对再交付):
   - [ ] 所有外键都有索引
   - [ ] 字符串长度合理(VARCHAR vs TEXT)
   - [ ] 金额用 DECIMAL 不用 FLOAT
   - [ ] 时间列带默认值
   - [ ] 多对多已建中间表

## 输出格式

用 ```sql 代码块输出完整脚本,最后附一句中文设计说明。

要点拆解:

四、加入支撑文件(渐进式加载的关键)

把长参考拆出去,正文才够精简。新建 conventions.md:

# 建表规范

## 命名
- 表名:小写蛇形复数,如 `users`、`order_items`
- 主键统一 `id BIGINT UNSIGNED AUTO_INCREMENT`(postgres 用 `BIGSERIAL`)
- 外键列 `<表名单数>_id`,如 `user_id`
- 时间列 `created_at`、`updated_at`,软删除 `deleted_at`

## 范式
- 默认满足第三范式,冗余字段需在表注释写明理由
- 多对多必须建中间表,命名 `<a>_<b>` 按字母序

## 索引
- 所有外键自动加普通索引
- 高频查询条件(如 status、tenant_id)加索引
- 软删除字段 deleted_at 不索引

## 类型
- 金额一律 DECIMAL(18,2)
- 布尔用 TINYINT(1)(mysql)或 BOOLEAN(postgres)
- 长文本 TEXT,短文本 VARCHAR 带长度

再建 templates/ddl.template.sql:

-- 表:{table_name} | 用途:{purpose}
CREATE TABLE {table_name} (
  id          BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
  -- 业务字段在此
  created_at  TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
  updated_at  TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  deleted_at  TIMESTAMP NULL,
  PRIMARY KEY (id),
  UNIQUE KEY uk_{table_name}_{unique_col} ({unique_col}),
  KEY idx_{table_name}_{fk_col} ({fk_col})
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='{purpose}';

-- 种子数据
INSERT INTO {table_name} (...) VALUES (...);

正文里用一句话引导 Claude "需要时读取 conventions.md / templates",它就会在该用的时候才加载——这正是 500 行正文红线的实践方式。

五、测试:两种触发路径都要验

新建/修改 Skill 后无需重启——Claude Code 监听 Skill 目录,会话内即时生效(前提是启动时该目录已存在)。开一个 git 项目,claude 进入会话。

路径 A:自动触发。输入一段贴合 description 的话:

帮我给一个多租户的内容管理平台设计数据库,要有文章、作者、栏目,作者属于某个租户

预期:Claude 自动加载 schema-designer,先扫描现有迁移(动态注入行展开为真实路径),再输出含三张表、租户外键索引、中间表(文章-栏目多对多)、种子数据的完整 DDL。

路径 B:手动调用 + 参数:

/schema-designer "电商订单 含商品 SKU 优惠券" postgres

预期:$requirement 展开为需求串,$dialect 展开为 postgres,输出改用 BIGSERIAL、BOOLEAN 等 PG 语法。

常见问题速查:

现象 原因 解决
输入 /schema 没有补全 启动时目录不存在 重启 Claude Code 让它开始监听新目录
自动不触发、手动能跑 description 没覆盖该说法 在 when_to_use 补触发词
触发太频繁误伤 description 过宽 加约束,如"仅当明确要建表时"
description 在清单里被截断 超 1536 字符 精简,把细节挪到 when_to_use 之外的正文

六、用 skill-creator 评估与迭代

Skill 不是写完就完。官方提供 skill-creator 内置能力,能跑 evals、做方差分析、优化 description 的触发准确率。

在会话里直接说:

帮我评估 schema-designer 这个 skill 的触发准确率,跑 10 条用例,
对一半是建表需求、一半是无关需求,看它会不会误触发

它会自动生成正负样本、统计触发命中、给出 description 改写建议。拿到结果后微调 description/when_to_use,再跑一轮,直到误触发率收敛。这一步是把"能用"提升到"好用"的分水岭。

七、分发:个人级 vs 项目级 vs 插件

实战案例:十秒落地一个评论系统

把上面所有步骤串起来。需求:给现有博客加评论,支持楼中楼。

直接对 Claude 说:

给博客加评论功能,要支持二级回复

Claude 加载 schema-designer 后产出(节选):

-- 表:comments | 用途:文章评论,支持二级嵌套回复
CREATE TABLE comments (
  id          BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
  article_id  BIGINT UNSIGNED NOT NULL COMMENT '所属文章',
  parent_id   BIGINT UNSIGNED NULL COMMENT '父评论id,NULL为一级评论',
  author_id   BIGINT UNSIGNED NOT NULL COMMENT '评论者',
  content     TEXT NOT NULL,
  created_at  TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
  updated_at  TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  deleted_at  TIMESTAMP NULL,
  PRIMARY KEY (id),
  KEY idx_comments_article_id (article_id),
  KEY idx_comments_parent_id (parent_id),
  KEY idx_comments_author_id (author_id),
  CONSTRAINT fk_comments_article FOREIGN KEY (article_id) REFERENCES articles(id),
  CONSTRAINT fk_comments_author FOREIGN KEY (author_id) REFERENCES users(id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='评论表';

INSERT INTO comments (article_id, parent_id, author_id, content) VALUES
  (1, NULL, 10, '好文章!'),
  (1, 1, 20, '同意,二级回复'),
  (1, NULL, 30, '学到了');

它自动给三个外键列都建了索引、用 parent_id 表达二级回复、附了种子数据——这正是规范文件 + 模板 + 自检清单合力产出的结果。下次任何建表需求,一句话即可。

工作流程总览

flowchart TD
    A[识别重复流程] --> B[设计:触发/输入/输出/支撑文件]
    B --> C[创建目录 ~/.claude/skills/name]
    C --> D[写 SKILL.md frontmatter+正文]
    D --> E[拆分长参考到支撑文件]
    E --> F[动态注入 !cmd + 参数 $N]
    F --> G{测试}
    G -->|自动触发| H[匹配 description]
    G -->|手动 /name| I[展开参数]
    H --> J[skill-creator evals]
    I --> J
    J -->|误触发/漏触发| K[调 description/when_to_use]
    K --> G
    J -->|通过| L[分发:个人/项目/插件]

延伸阅读

训练营适用性评估

参考来源

  1. Extend Claude with skills — Claude Code Docs — 官方权威文档,frontmatter 字段、目录规则、渐进式加载与字符串替换的源头(2026-07-09 更新)
  2. Claude Code Skills Complete Guide: SKILL.md, MCP, Subagents & Teams — 涵盖 Skill 与子代理、团队编排结合的完整指南
  3. How to Create Custom Claude Code Skills: Complete Tutorial (2026) — 2026 年版从零创建实战教程,含 frontmatter 详解
  4. Claude Code Skill Frontmatter: Every YAML Option Explained — 逐字段解释所有 frontmatter 选项及其运行时行为
  5. Inside Claude Code Skills: Structure, prompts, invocation — 从原理剖析 description 如何同时承担"说明"与"触发"双重角色

[!tip] 51学通信知识星球 星主:爱卫生(微信:gprshome201101)——公众号「51学通信」创办者,19 年通信行业运维与讲师经验,著有《GPRS网络信令实例详解》《EPC原理与实践》《5G核心网原理与实践》三本纸质书(各大电商平台有售)。 星球定位:深耕 5G 核心网、IMS、NFV/AI、云原生等 ICT 领域,主打运维岗位与信令分析。 当前规模:5200 篇主题 / 990 个回答,198 元/年。 加入福利:加入星球后请加爱卫生微信,拉您进知识星球年度陪伴与答疑群——不限量回复您的各种问题,另有群内分享。 AI 加持:51学通信知识星球已作为 skill 接入 WorkBuddy,使用 deepseek-4-flash 在海量星球帖子中精准找贴、找视频、找 FAQ 和案例,做总结、找文档和 PPT 等场景全覆盖。

51学通信知识星球海报-扫码加入