资讯详情

vibe-vibe 教程第六章精讲:数据持久化与数据库——从 JSON 文件到 PostgreSQL 的完整实战

📅 2026/10/10 11:57:30 | 华诺云谱 👁 阅读
vibe-vibe 教程第六章精讲:数据持久化与数据库——从 JSON 文件到 PostgreSQL 的完整实战
文档教程Vibe Coding示例工程【免费下载链接】vibe-vibeThe First Systematic Vibe Coding Open-Source Tutorial | From Zero to Full-Stack, Empowering Everyone to Build Products with AI | Live at: www.vibevibe.cn 首个系统化 Vibe Coding 开源教程 | 零基础到全栈实战让人人都能用 AI 开发产品 | 在线地址www.vibevibe.cn项目地址https://gitcode.com/datawhalechina/vibe-vibe点击查看免费下载本文围绕 Datawhale vibe-vibe 开源教程 第六章数据持久化与数据库 展开系统讲解从浏览器内存、JSON 文件到关系型数据库的持久化演进深入剖析 Drizzle ORM 的 Schema 定义、CRUD 与事务、索引、数据校验三道防线、备份意识以及 PostgreSQL 选型理由。读完本文你将能看懂 AI 生成的数据库设计与 CRUD 代码知道何时让 AI 加索引、查事务、扩 Schema并在实战中避开连接字符串、开发/生产环境混用等常见坑。文章中的源码级示例均来自仓库 demo-03-social-schema 与 demo-01-todo。序言为什么界面做好了数据却消失了当你的表单、对话、任务列表都能正常展示时会撞上一个尴尬问题每次刷新网页之前填写的内容全部不见。原因在于浏览器里默认处理的数据只存在于临时的内存中页面一旦刷新或关闭内存就被释放。老师傅给出的结论很直接数据是所有业务的基石。前端代码丢了可以重写UI 丑了可以换皮但数据库里的用户数据一旦丢失或错乱产品就彻底完了。这也解释了为什么后端开发往往比前端更讲究严谨性——因为后端守护的是产品的灵魂。本章解决的核心问题是数据持久化让数据在刷新、关闭、重启之后依然存在并围绕怎么存、怎么查、怎么保证正确、怎么防丢失展开一整套可实战的知识体系。一、持久化第一步JSON 文件存储持久化不一定一开始就要安装复杂的数据库软件。最简单的方案是把前面章节在配置文件中学到的JSON格式利用起来把数据存成.json文件。每一条聊天记录或用户信息本质上都是一段文本。把它写入硬盘上的文件下次再读取文件即可恢复。这种方式的实践意义在于它让你瞬间理解数据库的本质——无非就是高效地读写硬盘上的文件。JSON 文件足够直观、零依赖适合原型阶段或数据量极小的场景。二、关系型数据库把数据库想成超级 ExcelJSON 文件虽简单但一旦数据量变大问题就暴露了想找出所有住在北京且年龄大于 20 岁的用户就必须遍历整个文件效率极低。此时需要引入Relational Databases关系型数据库。关系不是指人际关系而是表和表之间通过共同字段连接起来——例如用户表与订单表靠user_id关联。老师傅建议把它想象成一个超级 Excel只需掌握五个关键概念概念类比说明Table表Excel 工作表如Users表Row行表里的一行代表一条具体数据如用户张三Column列表头定义数据有哪些属性姓名、年龄、邮箱Primary Key主键每行的唯一身份证号通常是id绝对不能重复Foreign Key外键关联其他表的线索如在Orders表中记录user_id即可顺藤摸瓜找到订单归属的用户如何判断 AI 设计的表结构好坏AI 交叉论证法新手往往难以一眼看出 Schema 设计是否合理。教程给出一个实战技巧——AI 交叉论证法俗称炼蛊让AI 1 号根据 PRD 设计好表结构并生成代码把生成的代码发给AI 2 号或 AI 3 号并提问作为一个资深数据库架构师根据我的 PRD 和实际业务场景这个设计是合理的设计吗有什么潜在的性能隐患或逻辑漏洞通常经过两轮这样的左右互搏就能得到一个相当健壮的数据库模型。这套方法在仓库中同样有落地demo-03-social-schema 演示了一个典型的用户-帖子-评论-点赞-关注-标签社交数据模型其中点赞表、关注表、帖子标签表都通过uniqueIndex防止重复数据正是交叉论证后常见的结果形态。三、Drizzle Schema用 TypeScript 定义表结构操作数据库的标准语言是 SQL而本教程使用Drizzle ORM——让你用熟悉的 TypeScript 代码操作数据库不必手写 SQL。Drizzle 通过 TypeScript 定义Schema表结构定义每张表有哪些列、什么类型AI 会根据 PRD 文档自动生成你的工作是审查 AI 生成的代码是否正确。老师傅强调数据库设计的关键是理解业务关系。AI 能处理技术实现但用户和订单是什么关系需要你理解业务。逐行读懂 AI 交出的 Schema以下代码来自教程正文与仓库 demo-03-social-schema/src/db/schema.ts 中的写法完全一致// src/db/schema.ts import { pgTable, serial, text, timestamp, integer } from drizzle-orm/pg-core export const users pgTable(users, { id: serial(id).primaryKey(), // 自增主键 email: text(email).notNull().unique(), // 必填且唯一 name: text(name), // 可选字段不加 .notNull() createdAt: timestamp(created_at).defaultNow(), }) // 关联表示例 export const posts pgTable(posts, { id: serial(id).primaryKey(), title: text(title).notNull(), authorId: integer(author_id).references(() users.id), // 外键关联 })关键 API 的含义pgTable定义一个 PostgreSQL 表结构。字段类型serial自增整数、text文本永远用 text 而不要用 varchar、boolean布尔、timestamptz带时区时间、integer整数、numeric精确小数金额必须用它。可选字段不加.notNull()的字段默认可选。.unique()约束字段值唯一。.references()定义表之间的外键关联。仓库中的真实 Schema 形态在 demo-03-social-schema/src/db/schema.ts 中可以看到更完整的实战写法users、posts、comments、likes、followers、tags、postTags七张表覆盖了一对一、一对多、多对多三类关系。其中两个细节值得注意export const likes pgTable(likes, { id: serial(id).primaryKey(), postId: integer(post_id).references(() posts.id).notNull(), userId: integer(user_id).references(() users.id).notNull(), }, (table) [ uniqueIndex(likes_post_user_idx).on(table.postId, table.userId), ])多对多关系通过中间表post_tags实现post_tags同时引用posts.id与tags.id联合唯一索引如likes_post_user_idx、followers_unique_idx确保同一用户对同一帖子只能点赞一次同一对关注关系不重复这正是AI 交叉论证法能产出的健壮设计。待办清单 demo 则展示了更轻量的 Schema一张todos表包含title、completedboolean默认false、category默认inbox、dueDate、order、createdAt恰好对应教程中表结构定义——每张表有哪些列、什么类型的最小完整示例。四、数据库操作CRUD、事务与索引掌握数据库操作只需理解三个核心概念。CRUD所有数据库操作的基石虽然不用手写 SQL但必须把CRUDCreate 增、Read 查、Update 改、Delete 删刻在脑子里——这是指挥 AI 操作数据的核心通用术语。仓库 demo-03-social-schema/src/operations.ts 用可交互的 CLI 逐一演示了 CRUD 与联表查询的 Drizzle 写法// 查询所有用户Read const allUsers await db.select().from(users) // 联表查询帖子列表含作者对应 SQL // SELECT posts.id, posts.content, users.nickname // FROM posts INNER JOIN users ON posts.user_id users.id // ORDER BY posts.created_at DESC const postsWithAuthor await db .select({ postId: posts.id, content: posts.content, author: users.nickname }) .from(posts) .innerJoin(users, eq(posts.userId, users.id)) .orderBy(desc(posts.createdAt)) // 更新昵称Update.returning() 返回更新后的行 const updated await db .update(users) .set({ nickname: 小红薯 }) .where(eq(users.nickname, 小红)) .returning()运行方式在demos/demo-03-social-schema目录下先pnpm seed填充示例数据pnpm demo交互式选择 CRUD、JOIN、GROUP BY 聚合等演示pnpm demo -- --all非交互式运行全部演示pnpm demo -- --demolikes只运行指定演示如点赞统计pnpm paginationOffset 与 Cursor 两种分页策略的实测对比pnpm advanced高级查询演示。事务保证数据完整性有些操作涉及多个数据库改动必须打包执行。例如转账——从 A 账户扣钱、给 B 账户加钱若扣钱成功而加钱失败数据就乱了。事务Transaction就是把多个操作打包成要么全成功、要么全失败的原子操作在处理金融、订单等关键业务时必不可少。仓库 demo-03-social-schema/src/transactions.ts 演示了转移帖子所有权这类典型事务场景将帖子和相关评论同时转给另一用户并演示失败回滚与删除前级联检查。需要特别留意其中注释揭示的一个现实约束Neon HTTP 协议不支持真正的事务因此演示采用db.batch([...])批量操作模拟并配合.onConflictDoNothing()处理唯一约束冲突若使用标准 TCP 连接的 PostgreSQL如本地实例则可通过 Drizzle 的db.transaction(async (tx) {...})获得真正的原子性。从源码结构看这正是教程不被 BaaS 捆绑、掌握数据库本身理念在实现层面的体现。索引加速查询数据多了以后查询会变慢。比如在百万用户中查找某个 email没有索引时数据库只能逐行扫描。索引Index就像书本的目录有了它数据库直接定位目标位置速度可提升几十倍甚至上千倍。但索引不是越多越好它占用额外空间增删数据时需要同步更新索引反而影响写入性能因此只在经常查询的字段上建索引如email、created_at特别注意PostgreSQL 不会自动给外键列创建索引——这是最常见的性能陷阱必须手动添加。在 demo-03-social-schema/src/db/schema.ts 中uniqueIndex(likes_post_user_idx)、uniqueIndex(followers_unique_idx)、uniqueIndex(post_tags_unique_idx)就是这种既防重复又加速查询的典型实践。另外分页演示源码 还从侧面印证了索引的价值Offset 分页在大偏移量下会退化为全表扫描性能差而基于索引定位的 Cursor 分页性能稳定、不受数据变动影响——这正是教程后续查询变慢了 → 让 AI 加索引建议的底层原因。五、数据完整性与校验三道防线数据存进去了但存得对不对邮箱填成hello格式不对、年龄填成-5范围不对、订单引用了一个不存在的用户 ID引用完整性——数据校验就是防止这种情况发生。校验共有三道防线第一道防线数据库约束。定义 Schema 时使用的.notNull()、.unique()、.references()就是数据库层面的约束。这些是铁律——即使代码有 bug数据库也会拒绝违规数据。第二道防线后端 API 校验。处理用户请求时AI 会自动加上校验逻辑邮箱格式、密码长度、枚举值范围等在数据到达数据库前拦截错误。第三道防线前端表单验证。用户提交前由浏览器先检查如input typeemail会自动验证邮箱格式HTML5 的required、min、max属性也能做基本校验。老师傅提醒三道防线各有用处。数据库约束是最后一道保险后端校验是主要防线前端校验是为了用户体验快速反馈不用等网络请求。绝不要因为有了前端校验就省略后端与数据库层面的保护——用户可以绕过前端直接调用 API。仓库实践drizzle-zod 让校验单一数据源仓库在第二道防线上做了很好的示范demo-03-social-schema/src/validation.ts 使用drizzle-zod的createInsertSchema()从 Drizzle 表定义自动生成Zod 验证规则再叠加业务规则import { createInsertSchema } from drizzle-zod import { users, posts, comments } from ./db/schema.js export const insertUserSchema createInsertSchema(users, { nickname: (schema) schema.min(1, 昵称不能为空).max(50, 昵称最多 50 字), }) export const insertPostSchema createInsertSchema(posts, { content: (schema) schema.min(1, 内容不能为空).max(2000, 内容最多 2000 字), }) export const insertCommentSchema createInsertSchema(comments, { content: (schema) schema.min(1, 评论不能为空).max(500, 评论最多 500 字), })这实现了单一数据源Single Source of Truth模式一份 Schema 同时用于数据库建表DDL、TypeScript 类型推导与运行时数据验证避免三处维护不一致。演示源码 validated-operations.ts 通过.safeParse()不抛异常、返回{ success, data?, error? }结构化结果验证了合法/非法数据空昵称被拒绝、空帖子内容被拒绝、超过 500 字的评论被拒绝。运行pnpm validate即可看到完整演示。而在 seed.ts 中插入数据前也会先执行insertUserSchema.parse(u)把第二道防线前移到数据写入环节。六、数据备份开发的底线在讲任何技术之前先讲数据备份意识。数据是产品的灵魂备份是开发的底线。很多人忽视备份直到某天数据库崩溃才发现所有用户数据丢失——这是灾难性的后果。自动化备份不是可选项而是必修课。备份策略必须包括自动备份每天执行多地备份云 本地各存一份定期恢复演练验证备份是否真的可用。灾难恢复演练的重要性不亚于备份本身——太多人做了备份却从未测试等到需要恢复时才发现备份文件已损坏。七、数据库选择为什么是 PostgreSQL为了实战教程先引入了SQLite——轻量级文件数据库无需安装非常适合开发测试。但为了扩展性最终推荐PostgreSQL。PostgreSQL 的托管方式Supabase vs Neon维度SupabaseNeon定位完整 BaaSBackend as a Service专注数据库本身附带能力Auth 认证、Storage 存储、Realtime 实时订阅、Edge Functions 等无服务器架构 PostgreSQL按需自动扩缩容适合场景快速验证 MVP、不想操心后端细节对后端有自定义需求的场景但老师傅强调本教程推荐使用标准的 PostgreSQL而不是被任何 BaaS 捆绑。标准 PostgreSQL 能让你更深入理解数据库核心概念迁移成本更低未来可以按需选择任意托管平台或自建——Supabase、Neon、Railway 等都只是 PostgreSQL 的不同托管方式你掌握的是数据库本身而非某个特定服务平台。这种不被捆绑的思路在 AI 时代尤为重要。主从库与高可用简单认知生产环境通常有一个主库负责写数据和多个从库负责读数据主库数据自动同步到从库。这样既能分散读取压力又能在主库故障时让从库顶上——这就是高可用的基本思路。这些属运维层面开发阶段一个数据库就够用托管平台会帮忙处理。让 AI 开发者无法拒绝的两个特性JSONB 支持PostgreSQL 虽是关系型数据库却能像 NoSQL一类不要求固定表结构的数据库存取灵活但缺少关系约束一样直接存 JSON。这意味着可以把 AI 生成的那些结构不确定的复杂数据直接存入既有规则SQL又有灵活性NoSQL。pgvector向量检索AI 时代的杀手锏。它可以存储和查询向量数据——AI 把文本转成的一串数字用来衡量两段话有多像。这是实现AI 长期记忆RAGRetrieval-Augmented Generation让 AI 回答时能查阅你存进去的资料的核心技术。选了 PostgreSQL等于为 AI 应用铺平未来的路。八、实战避坑连接字符串、环境分离与数据标记开发数据库 vs 生产数据库专业团队通常会有两套数据库开发环境用来测试调试生产环境给真实用户使用。最佳实践是分离环境但学习阶段用一套数据库快速上手可以接受——直接在云端数据库开发部署时无需迁移数据省去很多麻烦。当应用有真实用户后强烈建议分离开发与生产环境避免数据污染与安全风险。数据标记如何区分测试数据与真实数据既然开发和生产共用数据库怎么区分测试数据与真实数据两个办法上线前手动清理测试数据在表设计时加isTest或isDev字段开发时写入的数据都标记为true上线后查询时过滤掉。当需要删除测试数据时直接告诉 AI 把所有测试数据删掉它会生成类似DELETE FROM users WHERE isTest true的代码。你看得懂这行代码的含义——只删除标记为测试的数据。这就是isTest字段的作用它像一道安全闸门确保只删测试数据不会误伤真实用户。Connection URL连接字符串格式经常能看到Error: Invalid URL的报错。连接数据库就像寄信格式必须严格遵守postgresql://用户名:密码主机地址:端口/数据库名任何一个标点符号出错或密码中包含需要转义的特殊字符都会导致连接失败。仓库中的连接实践可见 demo-03-social-schema/src/db/index.ts通过dotenv读取环境变量DATABASE_URL交给neondatabase/serverless的neon()创建连接再传入drizzle()得到数据库实例——连接字符串不写死在代码里而是放在.env中这是管理连接字符串的基本安全习惯。学完本章后看懂 AI 的设计知道它在做什么老师傅建议回到第四章的技术文档看看 AI 设计的数据模型。现在你能看懂那些表结构、关联关系和索引了如果 AI 的设计有问题你能发现如果没问题就放心用。掌握这些知识不是为了自己设计数据库而是为了能看懂 AI 的设计知道它在做什么。什么时候需要调整查询变慢了→ 让 AI 加索引数据不一致了→ 让 AI 检查事务需要新功能了→ 让 AI 扩展 Schema。大部分时候 AI 的设计已经足够好你只需要看得懂知道怎么让 AI 优化。延伸阅读本章小节导航本章内容在仓库中还对应以下分篇相对路径已转换为仓库根目录起点6.0 领取你的数据库注册 Neon/Supabase 免费套餐创建数据库实例获取连接字符串6.1 数据存储演进从 CSV 到 JSON 再到数据库的演进路径本土化案例豆瓣电影评分表6.2 数据库基础概念表、行、列、主键、外键、关联本土化案例美团外卖表关系6.3 如何操作数据库认识 Drizzle、Prisma 等 ORM理解 AI 生成的 CRUD 代码6.4 数据库设计与优化AI 交叉论证法、索引策略、行级安全RLS、连接管理、性能诊断。配套实战代码位于 demo-03-social-schema社交数据模型、CRUD、事务、分页、校验、高级查询全流程演示与 demo-01-todo待办清单的最小 Schema 示例。此外本章还承接 第五章界面(UI)与交互(UX) 的界面能力并为 第七章后端 API 开发 打下数据层基础。小结数据持久化是产品从能看走向能用的关键一跃。从 JSON 文件到关系型数据库从看懂 Drizzle Schema 到掌握 CRUD、事务、索引与三道防线再到建立备份意识、选择不被捆绑的 PostgreSQL——本章真正交付的不是让你手写数据库的能力而是与 AI 高效协作的数据素养看得懂 AI 的设计、知道风险点在哪、清楚何时该让 AI 出手优化。牢记老师傅那句话数据库设计的关键是理解业务关系AI 能处理技术实现而业务关系需要你来把握。赞分享文档教程Vibe Coding示例工程【免费下载链接】vibe-vibeThe First Systematic Vibe Coding Open-Source Tutorial | From Zero to Full-Stack, Empowering Everyone to Build Products with AI | Live at: www.vibevibe.cn 首个系统化 Vibe Coding 开源教程 | 零基础到全栈实战让人人都能用 AI 开发产品 | 在线地址www.vibevibe.cn项目地址https://gitcode.com/datawhalechina/vibe-vibe点击查看免费下载相关推荐Calico Goldmane 网络流量聚合服务架构、gRPC API 与实战接入指南Calico Goldmane 网络流量聚合服务架构、gRPC API 与实战接入指南 Goldmane 是 Calico 项目中的网络流量Flow聚合服文档教程Vibe Coding示例工程Lighthouse审计数据持久化终极指南从JSON文件到数据库集成的完整方案Lighthouse审计数据持久化终极指南从JSON文件到数据库集成的完整方案 Lighthouse是Google开发的自动化网站性能审计工具能够生成包含开发工具测试性能测试前端Vibe Coding 环境搭建实战从新电脑到 Node.js、pnpm 与 AI 编程工具的完整落地vibe-vibe 第一章Vibe Coding 环境搭建实战从新电脑到 Node.js、pnpm 与 AI 编程工具的完整落地vibe vibe 第一章 导读 本篇指南是 Dat文档教程Vibe Coding示例工程上一篇RyzenAdj 完全教程免费改写 AMD 笔记本功耗墙三条命令找回被压住的性能下一篇Minecraft-Region-Fixer 完整上手指南免费修复 Minecraft 损坏区域文件的扫描、修复与避坑全流程创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。

↑