Coderblock

数据库入门:SQL、Postgres 与 Supabase 详解

了解关系型数据库如何组织信息、SQL 如何工作,以及为什么 Postgres 和 Supabase 经常搭配用于现代 Web 应用。本课还将介绍数据库模式设计、安全机制,以及 Coderblock 中实用的数据库工作流程。

2 min

为什么 Web 应用需要数据库

应用可以显示页面、收集数据或执行操作。但如果它需要记住某些内容,该怎么办?

预约平台需要记住客户、服务和预约记录。 电商应用需要管理商品、订单和库存。 SaaS 平台需要知道哪些用户拥有账户、创建了哪些项目,以及具有什么权限。

这正是数据库存在的原因。

数据库是应用以结构化、持久化方式保存所需信息的地方。 如果没有数据库,许多数据可能只会暂时存在于浏览器中,关闭页面后就可能丢失。 而使用数据库后,应用可以保存信息并在之后重新读取,也可以让不同用户从不同设备访问这些信息。

数据库是应用的记忆

你可以把数据库理解为应用的永久记忆

前端负责展示信息。 后端负责执行业务逻辑。 数据库负责保存数据。

以预约应用为例:

前端 → 显示服务和日历 后端 → 检查可用时间和权限 数据库 → 保存用户、服务和预约记录

数据库有多种类型。文档数据库处理结构灵活的文档,键值数据库针对特定的快速访问场景进行了优化,而关系型数据库则将数据组织在彼此关联的表中。 SQL 和 Postgres 主要属于关系型数据库领域。Supabase 则以 Postgres 为核心,提供一套面向 Web 应用的后端服务。

关系型数据库:表、行与关系

关系型数据库使用来组织信息。 每张表通常代表一种实体。 在预约平台中,你可能会有:

  • profiles → 用户;
  • services → 可预约的服务;
  • bookings → 预约记录。

每张表中都包含:

  • ,用于描述数据的属性;
  • ,代表一条条具体记录;
  • 主键,用于唯一标识每条记录;
  • 外键,用于关联不同表中的记录;
  • 约束,用于阻止无效数据写入数据库。

例如,一条预约记录可以包含 profile_idservice_id。 这样,你就能准确知道是谁进行了预约,以及选择了哪项服务,而不必把用户和服务的全部信息重复复制到每条预约记录中。

为什么关系很重要?

假设某项服务更改了名称。 如果每条预约记录中都保存了一份服务名称,你可能需要更新成百上千条记录。 使用关系型数据库时,预约记录只需引用正确的服务即可。 因此,数据之间的关系能够减少重复和不一致,让产品的数据模型更加清晰。

什么是数据库模式?

创建数据库之前,需要先确定如何组织信息。 定义这一结构的表、列、关系、数据类型和约束统称为数据库模式(Schema)。 良好的模式设计,应该让数据库真实反映产品的运行方式。

创建新表之前,可以先问自己:

  1. 每条记录代表什么?
  2. 哪些信息是必填的?
  3. 哪些值必须唯一?
  4. 哪些实体之间需要建立关联?
  5. 谁可以读取或修改这些数据?

目标并不是创建尽可能多的表。 一张包含大量不同信息的巨型表可能很难维护;但如果把每个细小的数据都拆成单独的表,也会让系统变得不必要地复杂。

良好的模式需要在数据一致性、查询简单性与产品实际需求之间取得平衡。

什么是 SQL?

接下来就要介绍 SQL,它是 Structured Query Language(结构化查询语言)的缩写。 SQL 是与许多关系型数据库交互时使用的语言。

你可以用它来:

  • 创建数据结构;
  • 读取数据;
  • 添加记录;
  • 修改信息;
  • 删除记录;
  • 关联来自不同表的数据。

四种基础操作通常合称为 CRUD

  • Create → 创建
  • Read → 读取
  • Update → 更新
  • Delete → 删除

一个简单示例

假设我们要查询某位用户的预约记录。 可以使用下面的 SQL 查询:

SELECT id, start_time, status
FROM bookings
WHERE profile_id = 42
ORDER BY start_time;

这段查询实际上是在说:

“查询用户 42 的预约 ID、时间和状态,并按时间排序。”

SQL 还可以组合来自不同表的信息。 例如:

SELECT bookings.start_time, services.name
FROM bookings
JOIN services ON services.id = bookings.service_id;

这条查询将预约记录与对应的服务关联起来,从而同时获取预约时间和服务名称。

SQL 是声明式语言

SQL 的一个重要特点是,它是一种声明式语言。 你不必向数据库详细说明查找信息所需的每一步。 只需要告诉它你想得到什么结果,数据库就会自行决定如何执行查询。

SQL 还是一项被广泛采用的标准,不过不同数据库系统可能拥有各自特有的功能和扩展。 刚开始学习时,不需要掌握所有内容。 理解 SELECT、筛选、JOIN、分组、约束和事务等概念,就足以打下良好的基础。

什么是 Postgres?

这里需要明确区分两个概念: SQL 是语言,Postgres 是数据库。

Postgres,更准确地说是 PostgreSQL,是一款开源关系型数据库管理系统。 它是负责保存数据、执行约束并解析 SQL 查询的软件。

你可以这样理解二者之间的关系:

SQL → 你用来与数据库交流的语言 Postgres → 保存和管理数据的系统

Postgres 支持许多重要功能,例如:

  • 主键和外键
  • 事务
  • 索引
  • 视图
  • 约束
  • 高级数据类型

为什么事务很重要?

以电商应用为例。 客户购买商品时,系统可能需要:

  1. 创建订单;
  2. 扣减库存;
  3. 记录付款。

这些操作彼此关联。 如果第一步成功,但第二步失败,系统中可能已经生成了订单,库存却没有同步更新。

事务可以把多项操作视为一个整体:要么全部成功完成,要么由数据库将数据恢复到操作之前的状态。

那么索引呢?

索引用于提高特定查询的速度。 如果应用经常需要查询某位用户在特定日期的预约记录,添加索引就能显著提高查询效率。 但索引并不是没有成本:它会占用空间,并且在数据发生变化时需要额外维护。

因此,自动为每一列创建索引并不是好的做法。 索引应该服务于产品中真实存在的查询方式

什么是 Supabase?

如果说 Postgres 是数据库,那么 Supabase 就是围绕 Postgres 构建的后端平台。 它不会取代 Postgres。

相反,它提供了构建 Web 应用时通常需要的一系列服务,包括:

  • 身份验证与会话管理;
  • 文件存储;
  • 数据库管理工具;
  • 服务端函数;
  • 与数据相连的 API;
  • Row Level Security。

因此,最需要记住的区别是:

SQL 是语言,Postgres 是数据库,Supabase 是使用 Postgres 并提供应用开发服务的后端平台。

这一组合非常适合 Web 应用,因为它可以在一套集成式基础设施中管理数据、用户、文件和访问权限。

身份验证与授权:两个不同的概念

这里也需要区分两个概念。 身份验证解决的是:

“这位用户是谁?”

授权解决的是:

“这位用户可以做什么?”

Supabase Auth 可以处理注册、登录和会话。 而 **Row Level Security(RLS,行级安全)**可以规定某位用户能够读取或修改数据库中的哪些行。 以预约平台为例。 普通客户应该只能看到:

自己的预约记录。

管理员则可能需要看到:

所有预约记录。

他们都是已经通过身份验证的用户,但拥有不同的权限。

安全不能只依赖前端

在界面中隐藏按钮,并不意味着用户真的无法执行某项操作。 用户仍然可能尝试直接向后端发送请求。

因此,访问规则必须在后端和数据库中执行,而不能只依赖界面。 这正是 Row Level Security 的重要之处:它可以直接在数据库层定义访问规则。

Coderblock 中的数据库如何工作

在 Coderblock 的标准 Web 应用中,每个项目都有独立的 Supabase 环境,其中包含 Postgres、Auth、Storage、Deno Edge Functions 和 Row Level Security。 系统还预置了基础的个人资料结构和初始角色体系。

不同之处在于,你不一定要从手动配置数据库开始。 你可以直接通过聊天描述想要构建的功能。

例如:

“添加服务,包含时长、价格和启用状态。”

然后:

“创建与已登录用户关联的预约记录。”

接着:

“禁止客户查看其他客户的预约记录,并创建一个可以管理所有预约的管理员视图。”

智能体可以设计数据库模式、执行迁移、将 React 前端连接到后端,并配置所需的 RLS 策略。 之后,你可以在编辑器的 Backend 区域查看表、已验证用户、存储和函数。

在你继续通过对话修改应用时,实时预览也会同步更新。

最好的提示词不是“创建一个数据库”

使用 AI 应用构建器时,不要只提出这样的要求:

“为预约应用创建一个数据库。”

更有效的做法是描述产品模型。 请说明:

  • 主要实体有哪些;
  • 每个实体需要包含哪些信息;
  • 它们之间如何关联;
  • 哪些字段是必填的;
  • 哪些用户可以访问数据;
  • 这些用户可以执行哪些操作。

这样,AI 才能获得足够的信息,将产品描述转化为一致、合理的数据结构。

数据库入门最佳实践

即使不是数据库工程师,你也可以避开最常见的错误。

使用稳定的标识符

每张重要的表都应该拥有一个主键。 不要把姓名或电子邮箱等数据作为永久标识符,因为它们可能发生变化。

把规则放在靠近数据的位置

前端验证有助于改善用户体验,但不应该成为唯一的保护措施。 请使用:

  • 必填字段;
  • 唯一约束;
  • 外键;
  • 合适的数据类型;
  • 访问策略。

这样,无论请求来自哪里,数据库都能保护数据的完整性。

遵循最小权限原则

每位用户都应该只拥有完成其任务所必需的权限。 因此,请使用不同角色测试应用:

  • 匿名访客;
  • 已登录用户;
  • 管理员。

务必检查每种角色能够读取、创建、修改或删除哪些内容。

通过迁移管理数据库模式

数据库会随着产品一起变化。 添加新功能时,你可能需要创建表、增加列或修改关系。 使用受控迁移可以记录这些变化,并降低现有数据丢失的风险。 删除列或修改结构之前,务必确认它们已经不再被使用。

为产品建模,而不是为页面建模

这或许是最重要的一条原则。 一张表应该代表产品中的一个真实概念,而不只是界面中的某个页面。 仪表盘的设计可能彻底改变,但客户、预约和订单仍然代表相同的实体。 优先思考数据模型,也会让未来的前端迭代变得更加容易。

SQL、Postgres 和 Supabase:真正需要记住什么

如果你刚开始学习,不必记住几十个术语。

只需牢记下面的关系:

SQL → 用于查询和修改数据的语言 Postgres → 保存数据并执行查询的关系型数据库 Supabase → 使用 Postgres,并提供身份验证、存储、API、函数和 Web 应用开发工具的后端平台

在 Coderblock 中,这些概念已经融入应用创建流程。 你可以用自然语言描述应用需要记住什么、数据之间应该如何关联,以及谁可以访问这些数据。智能体可以负责全栈实现,而你则可以通过聊天检查并完善结果。

了解数据库的工作原理,还能帮助你完成一件更重要的事:更准确地描述你想构建的产品。 你不一定要亲自编写 SQL,但理解表、关系、角色、约束和授权,可以帮助你把想法变成真正的应用。它不仅能显示数据,还能切实地保存、关联并保护数据

立即在 Coderblock 上开始构建