跳转到内容

db-designer

从 API 规格推导数据库表结构,并生成相应方言的 SQL DDL。数据库类型在架构设计阶段(Phase 3 Step 0)确定,确保字段类型、约束、索引与安全策略都与 API 端点完全对齐。

  • Phase:Phase 3 — HOW(实现),Step 2
  • 触发条件
    • 用户请求数据库设计或 SQL DDL
    • 用户提到「Phase 3 Step 2」「DB 设计」「表结构」
    • API YAML 规格已存在
  • API 规格位于 logos/resources/api/api-designer 的产出)
  • logos-project.yaml 中已填写 tech_stack.database
  1. logos-project.yaml 读取 tech_stack.database 以确定方言
  2. 从 API 请求/响应结构中提取需要持久化的数据实体
  3. 设计带约束与审计字段的完整表结构
  4. 设计表关系与外键策略
  5. 设计安全策略(PostgreSQL 用 RLS,其他用应用层)
  6. 设计索引,并为每个索引说明理由
  7. 输出带完整注释的 DDL
特性PostgreSQLMySQLSQLite
UUID 主键UUID DEFAULT gen_random_uuid()CHAR(36) DEFAULT (UUID())TEXT PRIMARY KEY NOT NULL
时间戳TIMESTAMPTZDATETIME / TIMESTAMPTEXT(ISO 8601)
JSONJSONB(可索引)JSON(受限)TEXT(应用层)
行级安全ENABLE ROW LEVEL SECURITY不支持不支持
表注释COMMENT ON TABLECOMMENT = '...'-- @table-comment
列注释COMMENT ON COLUMN内联 COMMENT '...'-- @comment(上一行)

每张表都必须包含:

  • 主键(UUID 或自增,取决于方言)
  • 业务字段:从 API schema 映射而来,类型转换为 DB 类型
  • 审计字段created_atupdated_at
  • 软删除字段deleted_at(按需)
  • 约束NOT NULLUNIQUECHECKDEFAULT
  • API string + format: emailTEXT NOT NULL
  • API string + format: uuidUUID(PostgreSQL)/ CHAR(36)(MySQL)/ TEXT(SQLite)
  • API booleanBOOLEAN(PostgreSQL)/ TINYINT(1)(MySQL)
  • API string + enumTEXT + CHECK 约束
  • 货币字段 → INTEGER(分),禁止使用 DECIMAL/FLOAT
  • 外键列:必须建索引
  • 唯一约束列:自动创建唯一索引
  • 高频查询列:基于 API 查询参数
  • 复合索引:用于多条件查询(最左前缀规则)
  • 在写密集型表上避免过度索引
文件位置
DDL 文件logos/resources/database/
简单项目schema.sql(单文件)
复杂项目按领域拆分:auth.sqlbilling.sql

每张表与每一列都必须有注释。每个 DDL 块都包含一条 SQL 注释,标明来源 API 端点。

  • 货币值以 INTEGER 按分存储 —— 避免浮点精度问题
  • deleted_at 时间戳做软删除 而非物理删除
  • 先核心表,后辅助表 —— 先输出核心表供审查,再添加辅助表
  • 字段名与 API 对齐 —— 减少代码中不必要的转换
  • SQLite:使用 -- @comment 结构化注释(见 logos/spec/sql-comment-convention.md
  • SQLite:连接时必须执行 PRAGMA foreign_keys = ON