<!-- title: 造建表Skill：需求秒出DDL -->

## 概述

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

## 前置条件

- 已安装 Claude Code v2.1.196 及以上（用到 `${CLAUDE_PROJECT_DIR}` 等新特性）
- 熟悉命令行操作，能读懂 Markdown 与 YAML
- 本机装有一个 git 仓库用于演练（任意后端项目均可）
- 了解关系型数据库基本概念（主键、外键、索引）

## 一、先弄懂 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 存放位置决定作用域，务必先选对：

- **个人级**：`~/.claude/skills/<name>/SKILL.md`——你所有项目可用
- **项目级**：`.claude/skills/<name>/SKILL.md`——仅当前项目
- **嵌套级**：子目录里的 `.claude/skills/`，编辑该子目录文件时按需加载（适合 monorepo）
- **覆盖优先级**：企业 > 个人 > 项目；同名时项目级可覆盖内置 Skill

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

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

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

```markdown
---
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 代码块输出完整脚本，最后附一句中文设计说明。
```

要点拆解：

- **`description` 写法**：把核心用例放最前面，因为清单里只保留前 1536 字符。"做什么 + 何时用"挤进前一两句最稳。
- **`arguments` + `$requirement`**：声明命名参数，正文里用 `$requirement` 引用。若正文没出现 `$ARGUMENTS`，Claude 会把参数以 `ARGUMENTS: <值>` 追加。
- **`!`命令`` 动态注入**：反引号包裹的 `!`find ...`` 在 Claude 读到正文前**先执行**，输出直接替换该行。这里用来扫描现有迁移目录，让产出与现有库对齐。
- **`allowed-tools`**：列出本 Skill 激活期间可免确认使用的工具，免去逐条授权打断。

## 四、加入支撑文件（渐进式加载的关键）

把长参考拆出去，正文才够精简。新建 `conventions.md`：

```markdown
# 建表规范

## 命名
- 表名：小写蛇形复数，如 `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`：

```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/skills/`
- 想跟仓库走、团队共享 → 移到 `.claude/skills/schema-designer/` 并提交到 git（注意别提交敏感内容）
- 想跨项目分发并打包 hooks/agents → 给文件夹加 `.claude-plugin/plugin.json`，变成可安装插件，命名空间 `your-plugin:schema-designer`，避免与他人同名冲突

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

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

直接对 Claude 说：

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

Claude 加载 schema-designer 后产出（节选）：

```sql
-- 表：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` 表达二级回复、附了种子数据——这正是规范文件 + 模板 + 自检清单合力产出的结果。下次任何建表需求，一句话即可。

## 工作流程总览

```mermaid
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[分发:个人/项目/插件]
```

## 延伸阅读

- 官方 Skills 文档：<https://code.claude.com/docs/en/skills>——最权威的 frontmatter 与目录规则
- 字符串替换与动态注入：同上页面 "Available string substitutions" 章节，掌握 `$ARGUMENTS`、`${CLAUDE_SKILL_DIR}`、`${CLAUDE_PROJECT_DIR}`
- skill-creator：会话内调用即可跑 evals 与 description 优化，详见命令参考
- 内置 Skill 清单：`/doctor`、`/code-review`、`/batch`、`/debug`、`/loop`、`/run`、`/verify`，可作为 SKILL.md 写法范本
- AGENTS.md vs Skills：理解何时用持久规矩、何时用按需 Skill，避免在 CLAUDE.md 里堆流程

## 训练营适用性评估

- **适用类型**：中高级开发者训练营、企业内部"AI 研发提效"专题、数据库/后端方向实战营
- **教学时长**：讲解 30 分钟 + 动手 45 分钟 + evals 调优 30 分钟，合计约 2 课时
- **难度**：中。前置需理解 YAML 与目录概念
- **可迁移性**：高。掌握本套方法论后，学员可独立产出任意领域 Skill（接口文档、配置生成、安全审计等）
- **考核建议**：要求学员交付一个含支撑文件、通过 10 条 evals、误触发率低于 10% 的 Skill

## 参考来源

1. [Extend Claude with skills — Claude Code Docs](https://code.claude.com/docs/en/skills) — 官方权威文档，frontmatter 字段、目录规则、渐进式加载与字符串替换的源头（2026-07-09 更新）
2. [Claude Code Skills Complete Guide: SKILL.md, MCP, Subagents & Teams](https://duet.so/guides/claude-code-skills-complete-guide) — 涵盖 Skill 与子代理、团队编排结合的完整指南
3. [How to Create Custom Claude Code Skills: Complete Tutorial (2026)](https://www.aiforanything.io/blog/how-to-create-custom-claude-code-skills-tutorial-2026) — 2026 年版从零创建实战教程，含 frontmatter 详解
4. [Claude Code Skill Frontmatter: Every YAML Option Explained](https://allahabadi.dev/blogs/ai/claude-code-skills-frontmatter-complete-guide/) — 逐字段解释所有 frontmatter 选项及其运行时行为
5. [Inside Claude Code Skills: Structure, prompts, invocation](https://mikhail.io/2025/10/claude-code-skills/) — 从原理剖析 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学通信知识星球海报-扫码加入](https://wiki.500nian.com/images/zhixingqiu_qrcode.png)
