本节目标:学会用 AI 交叉论证法设计健壮的数据库,理解索引、安全、连接管理等关键概念,能在应用变慢时知道从哪里下手。
新手很难一眼看出 Schema 设计的好坏。你让 AI 设计了一套表结构,看着挺合理,但真的没问题吗?数据类型选对了吗?外键列有索引吗?约束完整吗?有没有性能隐患?
你自己可能看不出来,但另一个 AI 往往能发现问题。这就是"交叉论证法"的核心思路:
为什么这个方法有效?因为每个 AI 都有自己的"盲点"。AI 1 号设计表结构时,可能专注于业务逻辑的正确性,忽略了性能优化;AI 2 号以审查者的视角来看,更容易发现"这个外键没索引"、"这个列类型不对"之类的问题。
这就像写代码时的 Code Review——自己写的代码自己很难发现 bug,但同事一眼就能看出来。AI 之间的交叉审查也是同样的道理。
通常经过两轮"左右互搏",你就能得到一个相当健壮的数据库设计。不需要你自己是数据库专家,只需要会"让 AI 互相挑毛病"。
想象小红的外卖平台出了个 bug:某个 API 接口忘了加权限检查,任何用户都能看到其他人的订单——包括收货地址、手机号、消费记录。
如果权限控制只在代码里做,一个 bug 就能导致全部用户数据泄露。而代码里的 bug 是不可避免的——再优秀的程序员也会犯错,再严格的 Code Review 也有漏网之鱼。
行级安全(Row-Level Security, RLS) 是在数据库层面做权限控制。你定义一条规则:"用户只能看到自己的订单",数据库会自动过滤,无论从哪个入口查询都生效——API 接口、后台管理面板、数据迁移脚本,全部受约束。
这意味着即使代码有 bug,数据库也不会泄露其他用户的数据。RLS 就像银行金库的最后一道门——即使小偷突破了所有外围防线(代码层的权限检查),到了金库门前还是打不开(数据库层的 RLS)。
如果你用 Supabase,RLS 几乎是必须的。 因为 Supabase 的客户端 SDK 直接连数据库(通过 PostgREST),前端代码可以直接发 SQL 查询。没有 RLS 的话,任何人都可以在浏览器控制台里修改查询条件,看到所有用户的数据——这等于裸奔。
如果你用 Neon + 自己的后端 API,RLS 不是必须的。 因为用户的请求先经过你的后端代码,你可以在 API 层做权限控制(比如"只返回当前登录用户的订单")。但 RLS 作为额外的安全层仍然值得考虑——多一道防线总比少一道好,特别是当你的应用处理敏感数据(支付信息、个人隐私)时。
如果 AI 生成了 RLS 策略,检查三件事:
ALTER TABLE ... ENABLE ROW LEVEL SECURITY,否则策略不生效——就像手机设了密码但没开启锁屏,密码形同虚设。这是最常见的遗漏——策略定义和启用是两个独立步骤,缺一不可user_id)必须有索引,否则每次查询都要全表扫描来做权限过滤。这又回到了索引的重要性——没有索引的 RLS 策略,安全是安全了,但慢得让人受不了数据库里存的是你最宝贵的资产——用户数据。一旦泄露或损坏,后果可能是灾难性的。这一节讲三个最基本的安全措施。
SQL 注入是最经典的安全漏洞,已经存在了二十多年,至今仍然是 Web 应用被攻击的主要方式之一。
它的原理很简单:攻击者在输入框里填入恶意的 SQL 片段,如果后端代码直接把用户输入拼接到 SQL 语句里,这些恶意片段就会被当作 SQL 执行。比如在登录框的"用户名"里输入 ' OR 1=1 --,如果代码没做防护,就能绕过密码验证登录任何账号。
好消息是:使用 ORM(Drizzle/Prisma)就自动防住了。ORM 内部使用参数化查询——用户输入的内容会被当作"数据"而不是"代码"处理,无论输入什么都不会被当作 SQL 执行。这就像把用户的输入装进一个密封的信封里交给数据库,数据库只会读信封里的内容,不会把它当作指令执行。
但如果审查时看到 AI 生成了手写 SQL(字符串拼接的那种,比如 `SELECT * FROM users WHERE name = '${userName}'`),要警惕——这种写法没有参数化保护,容易被 SQL 注入攻击。应该改成 ORM 的写法或参数化查询。
这个道理很直觉:你不会把家里所有房间的钥匙都给快递员,只会给他大门的钥匙。你不会把银行卡密码告诉外卖小哥,只会付当次的餐费。数据库也一样。
应用连接数据库的账号,应该只有它需要的最小权限:能读数据、能写数据、能改数据,但不能删表、不能改表结构、不能创建新用户。管理员账号只在迁移和维护时使用。
为什么这很重要?因为应用代码是暴露在互联网上的,它是攻击者最容易接触到的入口。如果应用使用的数据库账号拥有管理员权限,一旦应用被攻破(比如通过某个未修复的漏洞),攻击者就能用这个账号做任何事——删除所有表、导出所有数据、甚至植入后门。
但如果应用账号只有读写权限,即使被攻破,攻击者也做不了太大的破坏——他能读到数据(这已经很糟了),但至少不能删表、不能改结构、不能影响数据库的正常运行。
数据是产品的灵魂。代码丢了可以重写,UI 丑了可以换皮,但如果用户数据丢了——用户的账号、订单、聊天记录、创作内容——你的产品就彻底完了。没有任何技术手段能从零恢复丢失的用户数据。
备份策略三要素: