5分钟搭建 Supabase 数据库:从建表到 RLS 策略,为 Refine 管理后台备好后端
2026/9/12 2:57:05 网站建设 项目流程

5分钟搭建 Supabase 数据库:从建表到 RLS 策略,为 Refine 管理后台备好后端

【免费下载链接】refineA React Framework for building internal tools, admin panels, dashboards & B2B apps with unmatched flexibility.项目地址: https://gitcode.com/GitHub_Trending/re/refine

Supabase 是一款基于 PostgreSQL 的开源后端即服务(BaaS)平台,集数据库、认证、存储和自动生成 API 于一体。本指南完全围绕Supabase 数据库的搭建展开:创建项目、设计表结构、建立外键关系、插入示例数据,并最终启用 REST API 与行级安全(RLS)策略。读完本文,你将拥有一个可被 Refine 直接消费的、带关系与约束的生产级数据模型,为后续自动生成列表、创建、编辑等管理后台页面打好基础。

本文不涉及前端与 API 调用细节,只专注数据库侧的实操——这也是后续连接 Refine 时最重要的前置步骤。


Step 1:创建 Supabase 项目

打开 Supabase 官网,点击Start your project。你可以使用 GitHub 账号或任意邮箱登录。

进入 Dashboard 后,点击New project并填写以下信息:

配置项说明
Name项目名称,任意填写,例如team-admin
Password数据库密码,请务必妥善保存
Region选择离你或你的用户最近的区域

点击Create new project后,大约 30 秒内,你就能得到一个运行在云端的 PostgreSQL 数据库,并且开箱即用地附带认证、存储和即时 API。

创建完成后会进入项目 Dashboard,核心功能区包括:

  • Table Editor——以可视化方式管理数据库结构
  • Authentication——添加用户与权限
  • Storage——上传和管理文件
  • Edge Functions——运行自定义后端逻辑

本指南的后续步骤都将在Table Editor中完成。


Step 2:认识 Table Editor

Table Editor 是设计数据模型的地方。你不需要写 SQL——当然也可以写——Supabase 提供了干净的 UI 让你可视化地定义一切。

每一张表都像一张电子表格,但带有类型、约束和关系。

创建新表时,你需要定义:

  • 表名(Table name)
  • (Columns,即字段)
  • 数据类型(Data types:textintegertimestamp等)
  • 默认值与约束(Default values & constraints)
  • 关系(Relationships,即外键)

Supabase 会在底层自动生成并处理对应的 SQL。你在 Table Editor 里构建的一切,都会立即通过 REST API 和 GraphQL 对外暴露(前提是策略允许,见下文 RLS 部分)。

Row Level Security(RLS)与策略速览

使用 Table Editor 创建表时,Row Level Security (RLS)默认是开启的。当 RLS 开启且没有任何策略(Policies)时,任何通过 REST 或 GraphQL API(使用公开的anon密钥)发起的请求都不会返回任何行

策略(Policies)是 PostgreSQL 规则,它们相当于为每个操作(SELECTINSERTUPDATEDELETE)隐式添加的WHERE子句。你需要在后面添加策略来有选择地开放访问。

角色映射关系如下:

  • anon:没有携带用户 JWT 的请求(仅使用公开密钥)
  • authenticated:携带有效用户 JWT 的请求(包括通过 Supabase Auth 创建的"匿名会话",这些会话同样使用authenticated角色)

你可以随时在表的Policies标签页中查看或修改 RLS。本指南先聚焦表结构,等结构就绪后再添加策略。


Step 3:创建你的第一张表

我们来创建一张简单的employees表——这是后续在 Refine 中常见的资源类型。

  1. Table Editor中点击New Table
  2. 命名为employees
  3. 添加以下列:
ColumnTypeDefault说明
iduuidgen_random_uuid()主键
nametext员工姓名
roletext职位或头衔
salarynumeric(12,2)可选薪资字段(若需严格金额运算,建议用整数存储最小货币单位)
created_attimestamptznow()记录创建时间

小提示:Table Editor 中的"Enable Row Level Security"开关默认是开启的。请保持开启状态——在添加显式策略之前,你的表都是受保护的。

点击Save后,表会被立即创建,并在策略允许的情况下通过 REST 对外可用。


Step 4:添加关联表

再创建一张departments表,用来演示关系(外键)是如何工作的。

  1. 点击New Table,命名为departments
  2. 添加:
ColumnTypeDefault
iduuidgen_random_uuid()
nametext

接下来回到employees表,点击Add Column,添加名为department_id的列:

  • 类型设置为uuid
  • Foreign Key下选择departments → id
  • 为更安全的删除行为,将外键行为设置为ON DELETE SET NULL

再次点击Save

至此,你建立了第一个关系:每个员工都属于一个部门。Supabase 会自动处理引用完整性并更新你的 schema。

这样的结构已经可以被 Refine 后续分析,并为你生成可用的列表、创建和编辑页面。


Step 5:插入示例数据

Table Editor中点击departments表,选择Insert Row,添加几条示例数据:

idname
(auto)Engineering
(auto)Marketing
(auto)HR

然后进入employees表插入:

idnamerolesalarydepartment_id
(auto)AliceEngineer85000(Engineering 的 id)
(auto)BobHR Specialist60000(HR 的 id)

现在你的数据已经上线。你可以直接在 Dashboard 中查看、编辑和筛选它们,也可以在SQL Editor标签页中用 SQL 查询。


Step 6:探索 SQL Editor

虽然 Table Editor 是可视化的,但 Supabase 同样支持完整的 PostgreSQL SQL。点击侧边栏的SQL Editor标签页即可。

在这里你可以:

  • 运行查询,例如SELECT * FROM employees;
  • 创建视图(views)、触发器(triggers)和函数(functions)
  • 保存并对 SQL 脚本进行版本管理

例如,在插入了departments并用真实的department_id关联员工之后,试试这条查询:

SELECT e.name, e.role, d.name AS department FROM public.employees e LEFT JOIN public.departments d ON e.department_id = d.id;

警告:Relation not found (42P01)如果看到ERROR: 42P01: relation "public.employees" does not exist

  • 确认创建表时点击了 Save。
  • 确认 schema 是public(默认值)且表名为小写employees
  • 刷新浏览器标签页——有时 SQL Editor 的元数据会滞后。
  • 确认你正处于创建该表的同一项目中。

小提示:没有结果或 department 为 NULL?LEFT JOIN会保留尚未设置department_id的员工。想看到部门名称,可以编辑员工记录,把正确部门的 UUID 粘贴到department_id字段中。

这种灵活性意味着你可以构建出 Refine(或任何前端)能直接使用的关联结构。


Step 7:启用 API 与策略

你在暴露的 schema 中创建的每张表都会自动获得一个 REST 端点,例如:

https://<project-ref>.supabase.co/rest/v1/employees

API 示例与密钥可以在Project Settings → API Docs中查看。

由于 RLS 是开启的,你必须先添加策略,数据才能对外可见。在表的Policies标签页中:

  1. 打开employees→ Policies → New Policy。
  2. 选择操作:SELECT。
  3. 模板选择 "Allow authenticated users"(或自定义)。
  4. 保存。UI 会展示对应的 SQL 供参考。

生成的读策略如下:

create policy "Authenticated can read employees" on public.employees for select to authenticated using (true);

插入策略(允许已认证用户添加行):

create policy "Enable insert for authenticated users only" on public.employees for insert to authenticated with check (true);

可选(仅限开发环境)更宽泛的读访问:

create policy "Dev read employees (anon + authenticated)" on public.employees for select to anon, authenticated using (true);

在生产环境前请务必移除这些宽松策略。

角色细节再强调一下:

  • 没有 JWT 的请求使用anon角色。
  • 已认证的用户会话(包括 Supabase 的匿名认证会话)映射到authenticated
  • 未认证请求的auth.uid()NULL——可以结合auth.uid() IS NOT NULL之类的检查来增强清晰度。

策略配置完成后,REST 调用示例:

curl -H "apikey: $SUPABASE_ANON_KEY" \ -H "Authorization: Bearer $USER_JWT" \ "https://<project-ref>.supabase.co/rest/v1/employees?select=*"

之后你还可以叠加更细粒度的策略(行归属、基于角色的过滤等)。


仓库视角:Refine 如何消费这张 Supabase 数据库

数据库就绪后,把目光转回本仓库,看看 Refine 是如何消费这张表的。仓库中的 Supabase 集成包位于 packages/supabase,其入口 src/index.ts 统一导出了createClientdataProviderliveProvider三个核心能力:

import { dataProvider, liveProvider, createClient } from "@refinedev/supabase"; const supabaseClient = createClient("SUPABASE_URL", "SUPABASE_KEY"); const App = () => { return ( <Refine dataProvider={dataProvider(supabaseClient)} liveProvider={liveProvider(supabaseClient)} /* ... */ > {/* ... */} </Refine> ); };

Data Provider:表结构直接映射为 CRUD 操作

在 packages/supabase/src/dataProvider/index.ts 中,dataProvidergetListgetOnecreateupdatedeleteOne等 Refine 数据方法翻译成对 Supabase 客户端链式查询的调用。几个值得关注的细节:

  • 分页getList默认currentPage = 1pageSize = 10mode = "server",通过query.range()实现服务端分页(见 dataProvider/index.ts)。
  • schema 支持:通过meta.schema可切换非publicschema(supabaseClient.schema(meta.schema))。
  • 关联查询:排序时可解析foreignTable.field形式,实现跨表排序;示例中meta.select传入"*, categories(title)"即直接拉起关联字段。
  • 过滤器映射:Refine 的CrudFilter运算符由 generateFilter.ts 逐条转换为 Supabase 查询,例如containsilike('%value%')betweengte(...).lte(...);运算符名映射见 mapOperator.ts。

Live Provider:基于 Postgres 实时变更订阅

packages/supabase/src/liveProvider/index.ts 利用 Supabase 的postgres_changes实时通道,把数据库中的INSERT/UPDATE/DELETE事件推送给 Refine 前端。它支持通过params.filters过滤订阅、通过params.ids只关注特定记录,并监听默认publicschema 下的指定表——也就是说,你在 Table Editor 里定义的表结构,天然就是实时订阅的订阅源。

开箱即用的示例项目

仓库中的 examples/data-provider-supabase 是一个可直接运行的完整示例,其 Supabase 客户端初始化见 src/utility/supabaseClient.ts,页面代码位于 src/pages/posts。以列表页 list.tsx 为例,它通过useTablemeta.select声明关联字段、配合useSelect加载分类下拉,展示了数据库关系如何直接映射成表格列、筛选器和表单选项。参考 README 运行示例:

npm create refine-app@latest -- --example contenteditable="false">【免费下载链接】refineA React Framework for building internal tools, admin panels, dashboards & B2B apps with unmatched flexibility.项目地址: https://gitcode.com/GitHub_Trending/re/refine

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询