db-designer
暂无简介
- License 许可
- Apache-2.0
- 最近更新
- 2026-10-18
- Stars
- ★ 581
- Forks
- 9
03 SKILL.md 正文
Skill: DB Designer
从 API 规格推导数据库表结构,生成对应方言的 SQL DDL。数据库类型由 Phase 3 Step 0 技术选型确定,确保字段类型、约束、索引和安全策略与 API 端点完全对齐。
触发条件
- 用户要求设计数据库或编写 SQL
- 用户提到 "Phase 3 Step 2"、"DB 设计"、"表结构"
- 已有 API YAML 规格,需要推导数据库设计
- 用户提供了数据模型需要转化为 DDL
核心能力
- 从 API 请求/响应结构推导表结构
- 读取
logos-project.yaml的tech_stack.database确定数据库类型 - 生成对应数据库方言的 SQL DDL
- 设计索引并说明设计理由
- 设计安全策略(RLS / 应用层权限)
- 为每张表、每个字段添加注释
前置依赖
logos/resources/api/中包含 API YAML 规格(api-designer 产出)logos-project.yaml的tech_stack.database已填写
如果 API 目录为空,提示用户先完成 Phase 3 Step 2 的 API 设计(api-designer)。如果 tech_stack.database 未填写,提示用户先完成 Phase 3 Step 0(architecture-designer)。
执行步骤
Step 1: 确认数据库类型
读取 logos/logos-project.yaml 的 tech_stack 字段,确定数据库类型和方言:
- PostgreSQL → 使用 UUID、TIMESTAMPTZ、RLS、JSONB 等特性
- MySQL → 使用 InnoDB、utf8mb4、TIMESTAMP 等特性
- SQLite → 使用 INTEGER PRIMARY KEY、TEXT 等简化类型
- 其他 → 与用户确认后选择最接近的方言
Step 2: 提取数据实体
从 API YAML 中提取所有需要持久化的数据实体:
- 扫描所有端点的
requestBody和responses,识别核心数据对象 - 区分"需要持久化"与"仅传输用"的数据:
- 有 CRUD 操作的对象 → 需要建表(如
users、projects) - 只出现在请求/响应中但不直接存储的 → 不建表(如
loginRequest)
- 有 CRUD 操作的对象 → 需要建表(如
- 为每个对象标注来源 API 端点
输出实体清单供用户确认:
从 API 规格中识别到 N 个需要持久化的数据实体:
| # | 实体 | 来源端点 | 核心字段 |
|---|------|---------|---------|
| 1 | users | auth.yaml → register, login | email, password, status |
| 2 | projects | projects.yaml → create, list, get | name, description, owner_id |
| 3 | subscriptions | billing.yaml → subscribe | plan, status, expires_at |
Step 3: 设计表结构
为每个实体设计完整的表结构,遵循当前数据库方言:
每张表必须包含:
- 主键(UUID 或自增 ID,视方言决定)
- 业务字段(从 API schema 映射,类型转换为数据库类型)
- 审计字段:
created_at、updated_at - 软删除字段:
deleted_at(按需) - 字段约束:
NOT NULL、UNIQUE、CHECK、DEFAULT
类型映射原则:
- API
string + format: email→TEXT NOT NULL(配合 CHECK 约束或应用层校验) - API
string + format: uuid→UUID(PostgreSQL)/CHAR(36)(MySQL) - API
integer→INTEGER/BIGINT - API
boolean→BOOLEAN(PostgreSQL)/TINYINT(1)(MySQL) - API
string + enum→TEXT + CHECK约束(列出枚举值) - 金额字段 →
INTEGER(存分值),禁止 DECIMAL/FLOAT
示例(PostgreSQL):
-- 用户表(来源:auth.yaml → register, login)
CREATE TABLE users (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
email TEXT NOT NULL UNIQUE,
password TEXT NOT NULL,
status TEXT NOT NULL DEFAULT 'pending'
CHECK (status IN ('pending', 'active', 'disabled')),
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
);
示例(SQLite — 使用 @comment 结构化注释):
-- 用户表(来源:auth.yaml → register, login)
CREATE TABLE users (
-- @comment 用户唯一标识,UUID v4 字符串
id TEXT PRIMARY KEY NOT NULL,
-- @comment 用户邮箱,已归一化为小写
email TEXT NOT NULL UNIQUE,
-- @comment Argon2id 密码哈希,仅存哈希
password_hash TEXT NOT NULL,
-- @comment 创建时间,ISO 8601 格式
created_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ', 'now')),
-- @comment 最后更新时间
updated_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ', 'now'))
);
-- @table-comment users 用户表,存储注册用户的核心信息
SQLite 注释约定:SQLite 不支持
COMMENT ON语法,必须使用-- @comment前置注释(字段)和-- @table-comment <表名> <描述>后置注释(表)。规则详见logos/spec/sql-comment-convention.md。
Step 4: 设计表间关联
根据 API 中的实体关系设计外键:
- 从 API 端点的嵌套路径和引用字段推导关联(如
/api/projects/:projectId/members→project_members表关联projects和users) - 确定关联类型(一对多、多对多)
- 设计外键约束和级联策略:
ON DELETE CASCADE:父记录删除时子记录跟随删除(如用户删除 → 项目删除)ON DELETE SET NULL:父记录删除时子记录保留但外键置空ON DELETE RESTRICT:父记录有子记录时禁止删除
Step 5: 设计安全策略
根据数据库类型设计对应的安全机制:
PostgreSQL — 行级安全(RLS):
ALTER TABLE projects ENABLE ROW LEVEL SECURITY;
CREATE POLICY projects_owner_policy ON projects
USING (owner_id = auth.uid());
- 所有包含用户数据的表启用 RLS
- 为每张表设计至少一条 Policy(owner / admin / public)
- 注明 RLS 策略与 API 认证方案的对应关系
MySQL — 应用层权限:
- 在表注释中标注数据访问权限(owner-only / admin / public)
- 不在 DDL 中实现权限控制,交由应用层处理
Step 6: 设计索引
为常见查询模式设计索引,每个索引附设计理由:
-- 用户按邮箱查找(登录场景,来源 S02)
CREATE UNIQUE INDEX idx_users_email ON users(email);
-- 项目按 owner 查找(项目列表,来源 S04 Step 1)
CREATE INDEX idx_projects_owner ON projects(owner_id);
索引设计原则:
- 外键列:必须建索引(避免 JOIN 全表扫描)
- 唯一约束列:自动创建唯一索引
- 高频查询列:根据 API 的查询参数判断
- 复合索引:多条件查询时考虑(最左前缀原则)
- 不过度索引:写多读少的表控制索引数量
Step 7: 输出完整 DDL
按以下顺序组织 DDL 文件:
- 文件头注释(来源、数据库类型、生成时间)
- 基础表(无外键依赖的表先建)
- 关联表(有外键依赖的表后建)
- 索引
- 安全策略(RLS / Policy)
- 表和字段注释:
- PostgreSQL:使用
COMMENT ON TABLE/COMMENT ON COLUMN - MySQL:使用内联
COMMENT - SQLite:使用
-- @comment(字段)+-- @table-comment(表),详见下方 SQLite 注释规则
- PostgreSQL:使用
每段 DDL 上方用注释标注来源 API 端点。
SQLite 注释规则(MUST Follow):
当 tech_stack.database 为 SQLite 时,必须使用以下结构化注释格式:
- 字段注释:在字段定义行的紧邻上方写
-- @comment <描述>- 与字段之间不允许空行(空行会断开关联)
- 多行注释:连续多个
-- @comment行自动拼接
- 表注释:在
CREATE TABLE ... ();语句紧邻下方写-- @table-comment <表名> <描述> - 约束行(
FOREIGN KEY、独立CHECK、UNIQUE)不需要-- @comment
输出规范
- 文件格式:SQL(方言由
tech_stack.database决定) - 存放位置:
logos/resources/database/ - 单文件输出:
schema.sql(简单项目);或按领域分文件:auth.sql、billing.sql(复杂项目) - 每张表必须有注释(PostgreSQL:
COMMENT ON TABLE;MySQL:COMMENT = '...';SQLite:-- @table-comment) - 每个字段必须有注释(PostgreSQL:
COMMENT ON COLUMN;MySQL: 字段定义后COMMENT '...';SQLite:-- @comment) - 每段 DDL 上方用 SQL 注释标注来源 API 端点
数据库方言差异速查
| 特性 | PostgreSQL | MySQL | SQLite |
|---|---|---|---|
| UUID 主键 | UUID DEFAULT gen_random_uuid() |
CHAR(36) DEFAULT (UUID()) 或 BINARY(16) |
TEXT PRIMARY KEY NOT NULL(应用层生成 UUID) |
| 时间类型 | TIMESTAMPTZ |
DATETIME / TIMESTAMP(注意时区处理) |
TEXT(ISO 8601 字符串) |
| JSON 支持 | JSONB(可索引) |
JSON(功能受限) |
TEXT(应用层 JSON 序列化) |
| 行级安全 | RLS (ENABLE ROW LEVEL SECURITY) |
不支持,需在应用层实现 | 不支持,需在应用层实现 |
| 表注释 | COMMENT ON TABLE t IS '...' |
CREATE TABLE t (...) COMMENT = '...' |
-- @table-comment t 描述 |
| 字段注释 | COMMENT ON COLUMN t.c IS '...' |
col_name TYPE COMMENT '...' |
-- @comment 描述(紧邻字段上方) |
实践经验
通用(所有数据库)
- 金额一律 INTEGER 存分值:禁止 DECIMAL/FLOAT,避免浮点精度问题
- 软删除:优先使用
deleted_at时间字段而非物理删除 - 审计字段:每张表包含
created_at和updated_at - 时间字段带时区:避免时区陷阱
- 字段名与 API 一致:DB 列名尽量与 API YAML 中的字段名对齐(如 API 用
userId→ DB 用user_id,映射规则明确即可),减少代码层的无谓转换 - 先出核心表再补辅助表:不要试图一次设计所有表——先输出核心业务表让用户 review,再补充辅助表
PostgreSQL 特有
- 主键:
id UUID DEFAULT gen_random_uuid() PRIMARY KEY - 时间类型:使用
TIMESTAMPTZ - RLS:所有表启用
ALTER TABLE ... ENABLE ROW LEVEL SECURITY; - JSONB:需要非结构化存储时优先使用 JSONB 并建 GIN 索引
MySQL 特有
- 主键:
id CHAR(36) DEFAULT (UUID()) PRIMARY KEY或自增 BIGINT - 时间类型:使用
TIMESTAMP(自动时区转换)或DATETIME(原样存储) - 字符集:建表时指定
CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci - 引擎:一律使用
ENGINE=InnoDB
SQLite 特有
- 主键:
TEXT PRIMARY KEY NOT NULL(应用层生成 UUID v4)或INTEGER PRIMARY KEY AUTOINCREMENT - 时间类型:使用
TEXT存储 ISO 8601 字符串,默认值DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ', 'now')) - 外键:须在连接时执行
PRAGMA foreign_keys = ON; - 注释:必须使用
-- @comment/-- @table-comment结构化注释(见logos/spec/sql-comment-convention.md) - 无触发器:
updated_at须在应用层刷新,不依赖ON UPDATE触发器
推荐提示词
以下提示词可以直接复制给 AI 使用:
帮我设计数据库基于 API 规格帮我推导数据库 DDL帮我设计 S01 涉及的数据库表帮我给现有表结构补充索引和 RLS 策略
04 同仓库更多 Skills
ui-ux-pro-max
UI/UX design intelligence. 67 styles, 96 palettes, 57 font pairings, 25 charts, 13 stacks (React, Next.js, Vue, Svelte, SwiftUI, React Native, Flutter, Tailwind, shadcn/ui). Actions: plan, build, create, design, implement, review, fix, improve, optimize, enhance, refactor, check UI/UX code. Projects: website, landing page, dashboard, admin panel, e-commerce, SaaS, portfolio, blog, mobile app, .html, .tsx, .vue, .svelte. Elements: button, modal, navbar, sidebar, card, table, form, chart. Styles: glassmorphism, claymorphism, minimalism, brutalism, neumorphism, bento grid, dark mode, responsive, skeuomorphism, flat design. Topics: color palette, accessibility, animation, layout, typography, font pairing, spacing, hover, shadow, gradient. Integrations: shadcn/ui MCP for component search and examples.
test-writer
暂无简介
test-orchestrator
暂无简介
slice-planner
暂无简介
scenario-architect
暂无简介
project-init
暂无简介