数据持久化与数据库
7.12 实战避坑案例
Tip
很多时候,阻挡你前进的不是深奥的算法,而是一个漏掉的指令,或者密码里一个不起眼的特殊字符。
1. 核心避坑:四大"鬼故事"
鬼故事一:消失的字段 (Schema 不一致)
- 现象:你在数据库里明明加了
vip字段,但在代码里写user.vip时,VS Code 死活报错说"不存在"。 - 真相:这就像是你给房子加盖了一层楼 (DB 变了),但你手里的施工图纸 (Client) 还是旧的。Prisma 不会自动更新它的类型定义。
- 解法:养成肌肉记忆,依然是那句咒语:
npx prisma generate
鬼故事二:连接数爆炸 (Serverless 的坑)
- 现象:本地开发一切正常。一上线,只要稍微有几个人同时访问,就报错
Current role has too many connections。 - 真相:Serverless 函数就像临时工。来一个请求,它就雇一个临时工,占一条电话线 (数据库连接)。请求一多,电话线就不够用了。
- 解法:使用 Supabase 的连接池 (PgBouncer)。
- 它像一个总机接线员,帮大家复用电话线。
- 配置:用那个端口是
6543的 URL,而不是5432的。
鬼故事三:密码里的"陷阱" (URL 编码)
- 现象:为了安全,你把数据库密码设成了
Lov3#C0de?。结果启动报错Invalid URL。 - 真相:在 URL 规则里,
#是锚点,?是查询参数。程序以为你的密码在#那里就结束了。 - 解法:
- 用 URL Encode 工具转义 (把
#变成%23)。 - 或者简单点:改个纯字母数字的密码。
- 用 URL Encode 工具转义 (把
鬼故事四:无限重生的客户端 (Next.js 热重载)
- 现象:开发时好好的,你保存了几次代码,终端突然报错
Too many clients already existed。 - 真相:Next.js 在开发模式下有"热重载"功能。每次你保存文件,它都会重新运行一遍代码。如果你把
new PrismaClient()直接写在文件里,每保存一次,就会创建一个新的数据库连接,旧的却没关掉。 - 解法:使用 单例模式 (Singleton)。把 prisma 实例挂载到
global全局变量上,防止被重复创建。// lib/prisma.ts const globalForPrisma = global as unknown as { prisma: PrismaClient } export const prisma = globalForPrisma.prisma || new PrismaClient() if (process.env.NODE_ENV !== 'production') globalForPrisma.prisma = prisma
3. 本章小结
- Generate:遇事不决,先跑一遍
npx prisma generate。 - 6543:在 Serverless 环境,永远连接这个端口 (连接池)。
- 转义:别让密码里的特殊字符把你挡在数据库门外。
- 单例:Next.js 里必须用
global缓存 Prisma 实例,否则热重载会把数据库连爆。