用途
Supabase Schema from Requirements 用于把业务需求翻译成 Supabase 内可用于生产的 Postgres 架构,覆盖从规格说明到迁移应用的完整路径:实体抽取、带正确类型与约束的表、行级安全(RLS)策略、性能索引、时间戳触发器,以及 TypeScript 类型生成。资料指出,早期做对该设计很重要,因为每个下游功能——认证、存储、实时、边缘函数——都依赖设计良好的数据表。
前置条件
- 已安装 Supabase CLI(npm install -g supabase)并已链接项目(supabase link)
- 项目中已安装 @supabase/supabase-js v2+
- 有标明实体与访问规则的业务需求、PRD 或规格文档
- 本地 Supabase 已运行(supabase start),或已链接的远程项目
主要能力与使用方式
第 1 步:解析需求并创建迁移
阅读需求文档,抽取实体、属性、关系和访问控制规则,将每个实体映射为一张 Postgres 表。资料以项目管理应用为例给出实体抽取示例:
| 实体 | 关键列 | 关系 |
|---|---|---|
| Organization | name, slug, plan | 拥有多个 Projects、多个 Members |
| Project | name, description, status | 属于 Organization,拥有多个 Tasks |
| Task | title, priority, status, due_date | 属于 Project,分配给 User |
| Member | role(owner/admin/member) | 连接 User 与 Organization 的联结表 |
创建迁移文件:
npx supabase migration new create_tables
# 生成:supabase/migrations/TIMESTAMP_create_tables.sql
使用标准 Postgres 数据类型(uuid、text、integer、boolean、timestamptz、jsonb)编写迁移 SQL。完整可运行迁移(项目管理应用——表、外键、索引、moddatetime 触发器)见 references/worked-schema-examples.md。
数据类型选择指南:
| 使用场景 | 类型 | 说明 |
|---|---|---|
| 主键 | uuid | 始终配合 uuid_generate_v4() 默认值 |
| 名称、标题 | text | 在 Postgres 中优于 varchar |
| 计数、排名 | integer | 序列使用 bigint |
| 标志 | boolean | 显式默认为 true 或 false |
| 时间戳 | timestamptz | 绝不使用无时区的 timestamp |
| 灵活数据 | jsonb | 可查询 JSON;用于设置、元数据 |
| 列表 | text[] | 用于简单标签或标记的 Postgres 数组 |
第 2 步:添加行级安全策略
所有对客户端暴露的表都必须启用 RLS。先编写可复用的安全定义者(security definer)辅助函数,再编写调用它们的各表策略。单表骨架示例:
alter table public.organizations enable row level security;
create policy "Users read own orgs"
on public.organizations for select
using (public.is_org_member(id));
完整策略集——is_org_member / is_org_admin 辅助函数,以及 organizations、members、projects、tasks 上所有 select/insert/update/delete 策略——见 references/rls-policies.md。策略命名按“谁 + 什么操作”进行(如 “Admins manage members”、“Assignee updates tasks”)。
第 3 步:应用迁移并生成类型
# 应用到本地
npx supabase db reset
# 或推送到已链接的远程项目
npx supabase db push
# 从实时架构生成 TypeScript 类型
npx supabase gen types typescript --local > types/supabase.ts
将生成的 Database 类型作为泛型参数传给 createClient(参见 import type { Database } from './types/supabase'),从而在每次查询上获得端到端类型安全。完整的类型化客户端演练——类型化插入、外键连接、嵌套多表连接和 RLS 强制检查——见 references/typescript-client.md。
输出
- supabase/migrations/ 下的 SQL 迁移文件,包含所有表、约束和索引
- 与需求中访问控制规则相匹配的 RLS 策略
- 用于可复用授权检查的辅助函数(is_org_member、is_org_admin)
- 用于自动管理 updated_at 的 moddatetime 触发器
- types/supabase.ts 中生成的 TypeScript 类型,用于类型安全客户端查询
- 在频繁过滤的列(status、due_date)上的部分索引
错误处理
| 错误 | 原因 | 解决方案 |
|---|---|---|
| 42P07: relation already exists | 迁移中的表名冲突 | 使用 create table if not exists 或重命名表 |
| 23503: foreign key violation | 插入引用了不存在的父行 | 先插入父行,或检查 UUID |
| 42501: insufficient privilege | RLS 辅助函数权限 | 在函数定义中添加 security definer |
| 42883: function uuid_generate_v4() does not exist | 未启用扩展 | 添加 create extension if not exists "uuid-ossp" |
| supabase db push 成功但表缺失 | 迁移已被记录 | 检查 supabase_migrations.schema_migrations 并修复 |
| PGRST204: column not found | TypeScript 类型不同步 | 重新运行 npx supabase gen types typescript --local > types/supabase.ts |
| new row violates row-level security | RLS 策略阻止了操作 | 验证 auth.uid() 是否与预期值匹配;检查策略 using 子句 |
| moddatetime 触发器失败 | 未启用扩展 | 在迁移顶部添加 create extension if not exists "moddatetime" |
适用场景
需要把规格转化为数据库表、设计多租户或带访问控制的 Supabase 数据模型、并希望获得类型安全客户端查询的场景。资料给出的示例包括项目管理应用与电商架构(不同领域、同一模式):完整电商迁移 SQL——stores、products、orders、order_items 及外键和索引——见 references/worked-schema-examples.md,配套的类型化客户端查询见 references/typescript-client.md。
限制与后续
资料未提供收费、价格、平台可用性等具体信息。若需在此架构之上集成认证、文件存储和实时订阅,可继续使用 supabase-auth-storage-realtime-core。
参考资料
- Row Level Security Guide
- Database Migrations
- Supabase CLI Reference
- JavaScript Client — Select
- TypeScript Support
- PostgreSQL Data Types