存数据:给网站接上真正的数据库
现在你的作品数据是写死在代码里的。每次想加一个新作品,都要改代码、重新部署。
这一关接入数据库,让作品数据可以动态管理。
为什么需要数据库?
想象一下,如果你的作品集有 50 个作品,每次更新都要改代码、推 GitHub、等 Vercel 部署……这太麻烦了。
数据库解决的就是这个问题:把数据和代码分开。数据存在数据库里,代码只负责读取和显示。你想加一个新作品,直接在数据库里插入一条记录,网站立刻更新,不需要改代码。
什么是 Supabase?
Supabase 是一个"开源的 Firebase 替代品",提供:
- PostgreSQL 数据库:功能强大的关系型数据库
- REST API:自动生成,不需要手写接口
- 实时订阅:数据变化时自动推送给前端
- 用户认证:内置登录注册功能(下一章会用到)
- 文件存储:存图片、文件等
免费计划包含:2 个项目、500MB 数据库、1GB 文件存储,对个人项目完全够用。
关系型数据库基础
Supabase 用的是 PostgreSQL,一种关系型数据库。数据存在"表"里,就像 Excel 表格:
| id | title | description | tags | created_at | |----|-------|-------------|------|-----------| | 1 | 美食网站 | 城市美食探索... | 前端,React | 2024-01-01 | | 2 | 作品集 | 个人作品展示... | Next.js | 2024-01-15 |
每一行是一条记录,每一列是一个字段。
SQL 是操作数据库的语言。你不需要学 SQL,AI 会帮你写。但知道几个基本操作:
SELECT- 查询数据INSERT- 插入数据UPDATE- 更新数据DELETE- 删除数据
第一步:创建 Supabase 数据库
Supabase 是一个免费的云数据库服务,不需要自己搭服务器。
- 访问 supabase.com,用 GitHub 账号登录
- 点击 "New Project",填写项目名称,选择离你最近的服务器区域(推荐 Singapore)
- 等待项目创建完成(约 1 分钟)
项目创建好后,在左侧菜单点击 "Table Editor",然后对 AI 说:
帮我在 Supabase 里创建一个 works 表,用来存储作品数据,字段包括: - id(自增主键) - title(作品标题,文本,必填) - description(作品描述,文本) - tags(标签,文本数组) - image_url(封面图片链接,文本) - project_url(项目链接,文本) - github_url(GitHub 链接,文本) - created_at(创建时间,自动填充) 给我 SQL 语句,我在 Supabase 的 SQL Editor 里执行。
在 Supabase 左侧菜单点击 "SQL Editor",粘贴 AI 给的 SQL,点击 Run 执行。
第二步:连接数据库
对 AI 说:
帮我把 Next.js 项目连接到 Supabase: 1. 安装 @supabase/supabase-js:npm install @supabase/supabase-js 2. 在 .env.local 里添加: NEXT_PUBLIC_SUPABASE_URL=(从 Supabase 项目设置里复制) NEXT_PUBLIC_SUPABASE_ANON_KEY=(从 Supabase 项目设置里复制) 3. 创建 lib/supabase.ts,初始化 Supabase 客户端 4. 创建 app/api/works/route.ts,实现: - GET:从数据库查询所有作品 - POST:向数据库插入新作品
获取连接信息:在 Supabase 项目里,点击左侧 "Settings" → "API",复制 Project URL 和 anon public key。
第三步:从数据库加载作品
对 AI 说:
更新作品页,从数据库加载作品数据: 1. 作品页改为从 /api/works 接口获取数据 2. 加载时显示骨架屏(灰色占位块) 3. 加载完成后显示真实数据 4. 如果数据库是空的,显示"暂无作品"的空状态 然后在 Supabase 的 Table Editor 里手动添加 2-3 条测试数据,刷新页面确认能正常显示。
关于"骨架屏"
骨架屏(Skeleton Screen)是一种加载状态的设计模式:在数据加载完成之前,显示和真实内容形状相同的灰色占位块。
相比传统的"加载中..."文字或旋转图标,骨架屏的优点是:
- 让用户感觉加载更快(因为页面结构已经出来了)
- 减少布局跳动(数据加载完成后,布局不会突然变化)
Facebook、LinkedIn、YouTube 都在用骨架屏。
关于 Supabase 的 Row Level Security(RLS)
Supabase 默认开启了 RLS(行级安全策略),这意味着即使你有 anon key,也不能直接读写数据库,需要先配置权限策略。
如果你发现数据查不到,可能是 RLS 的问题。对 AI 说:
我的 Supabase 查询返回空数据,可能是 RLS 的问题。 帮我配置 works 表的 RLS 策略,允许所有人读取(SELECT), 只允许认证用户写入(INSERT/UPDATE/DELETE)。
通关条件
完成以下三步即可通关:
- Supabase 数据库已创建,works 表存在
- 作品页从数据库加载数据(不再是写死的静态数据)
- 在 Supabase 里添加数据后,刷新页面能看到新数据
卡住了?
- 连接失败?检查
.env.local里的 URL 和 Key 是否正确,注意不要有多余的空格 - 数据查不到?在 Supabase 的 Table Editor 里确认数据存在,让 AI 检查查询语句
- 环境变量不生效?修改
.env.local后需要重启开发服务器(npm run dev) - RLS 报错?让 AI 帮你配置 Supabase 的行级安全策略
通关条件
完成以下三步即可通关:
- Supabase 数据库已创建,works 表存在
- 作品页从数据库加载数据(不再是写死的静态数据)
- 在 Supabase 里添加数据后,刷新页面能看到新数据
卡住了?
- 连接失败?检查
.env.local里的 URL 和 Key 是否正确,注意不要有多余的空格 - 数据查不到?在 Supabase 的 Table Editor 里确认数据存在,让 AI 检查查询语句
- 环境变量不生效?修改
.env.local后需要重启开发服务器(npm run dev) - RLS 报错?让 AI 帮你配置 Supabase 的行级安全策略