使用 ChatGPT、Codex 修改表单、接口或者数据入库逻辑时,经常会遇到一种很隐蔽的问题:

接口没有报错,页面也能正常提交,但数据库里的异常数据却越来越多。

常见表现包括:

  • 页面上明明限制了必填,数据库里还是出现空值;
  • 前端不允许输入负数,接口却能直接写进去;
  • 枚举字段本来只能有几个值,库里却慢慢出现各种脏值;
  • 字段缺失以后,后端自动补了默认值;
  • 单个接口测试正常,过一段时间才发现数据越来越难清理;
  • ChatGPT、Codex已经“加了校验”,但真正的数据边界并没有建立起来。

这类问题很多时候不是:

没有校验。

而是:

校验只做在了其中一层。


一、前端校验通过,不代表数据一定安全

例如注册页面规定:

  • 年龄必须大于0;
  • 邮箱不能为空;
  • 状态只能选择“启用”或“禁用”。

页面上确实无法提交错误内容。

但如果后端接口本身没有同样的限制,那么别人完全可以绕过页面,直接调用API。

例如直接发送:

age = -10

或者:

status = test

如果后端照单全收,数据库就会保存这些值。

所以要记住:

前端校验主要改善用户体验。

真正决定数据能不能进入系统的,应该是:

后端校验。


二、接口没有报错,有时候反而更危险

假设字段要求必须填写手机号。

ChatGPT、Codex为了“避免接口失败”,可能写成:

如果phone为空,就自动补一个空字符串。

这样接口确实不会报错。

但数据库里会慢慢出现:

phone = ""

表面看系统运行很稳定。

实际上异常数据正在不断积累。

所以有时候:

没有报错,不代表代码更健壮。

它也可能只是:

把原本应该暴露的问题悄悄吞掉了。


三、默认值最容易把错误藏起来

默认值本身不是问题。

真正的问题是:

把业务错误当成字段缺失来处理。

例如订单状态正常只允许:

  • pending
  • paid
  • cancelled

如果传入一个未知状态,代码却自动变成:

pending

接口就会正常返回。

但你已经失去了一个重要信号:

上游为什么会传错?

时间久了以后,系统里可能出现大量“看起来合法,实际来源异常”的数据。

所以默认值应该用于:

真正允许缺省的字段。

而不是用来掩盖非法输入。


四、数据库约束是最后一道防线

即使后端已经做了校验,也不代表数据库什么都不用管。

因为数据可能来自:

  • API;
  • 后台脚本;
  • 定时任务;
  • 数据同步;
  • 管理后台;
  • 人工SQL。

如果数据库完全没有约束,那么任何一个入口漏掉校验,都可能写入异常数据。

常见数据库约束包括:

  • NOT NULL;
  • UNIQUE;
  • CHECK;
  • 外键;
  • 合理的数据类型。

它们的作用不是代替业务代码。

而是:

在最后一道关口阻止明显非法数据进入。


五、业务规则不能只靠字段类型

例如库存字段定义成:

INTEGER

只能说明它是整数。

但业务真正要求可能是:

库存不能小于0。

数据库类型本身并不能保证这一点。

同样:

VARCHAR

也不能保证:

  • 状态值合法;
  • 邮箱格式正确;
  • 业务编码符合规范。

所以数据正确性通常要同时考虑:

类型正确 + 值合法 + 业务关系成立。


六、字段之间的关系更容易被忽略

很多脏数据不是单字段错误,而是:

几个字段单独看都对,组合起来却不合理。

例如:

status = cancelled

但是:

paid_at 仍然有支付时间。

或者:

订单显示已退款,

但:

refund_amount = 0

每一个字段类型都没有问题。

可整体状态已经互相矛盾。

这类规则通常属于:

业务不变量。

ChatGPT、Codex改字段校验时,不能只检查单字段,还要检查字段之间的关系。


七、为什么脏数据经常不是立刻发现?

因为多数接口只验证:

请求有没有成功。

例如返回:

200 OK

开发者就认为任务完成了。

但真正的数据问题可能几周以后才暴露:

  • 报表统计对不上;
  • 搜索结果异常;
  • 状态筛选漏数据;
  • 数据迁移失败;
  • 新功能无法兼容旧脏数据。

所以数据校验不能只看:

接口能不能跑通。

还要继续问:

最终写进数据库的数据是不是符合业务规则。


八、最稳的是分三层做校验

可以把数据校验分成三层。

第一层:前端

负责及时提醒用户:

  • 必填;
  • 格式;
  • 输入范围。

第二层:后端API

负责真正的业务判断:

  • 当前值是否合法;
  • 用户是否有权修改;
  • 字段组合是否成立;
  • 状态是否允许这样变化。

第三层:数据库

负责兜底:

  • 非空;
  • 唯一;
  • 外键;
  • 基础范围限制。

三层的目的不完全一样。

但它们应该互相补充,而不是只依赖其中一层。


九、测试也要加入“非法数据”

很多测试只覆盖:

正常参数能不能成功保存?

这远远不够。

还应该主动测试:

  • 空值;
  • 负数;
  • 超长字符串;
  • 不存在的枚举值;
  • 错误外键;
  • 不合理字段组合;
  • 直接绕过前端调用API。

如果这些请求仍然全部返回成功,就说明校验可能做得不完整。


十、可以直接这样让ChatGPT、Codex检查

以后让 ChatGPT、Codex 加字段校验时,可以直接要求:

请不要只检查前端表单。继续检查后端API是否对必填、范围、枚举和字段组合做了独立校验;确认默认值是否会掩盖非法输入;再检查数据库是否存在必要的NOT NULL、UNIQUE、CHECK和外键约束。最后补充绕过前端直接调用API的非法参数测试,确认错误数据不会进入数据库。

这样比单纯说:

帮我把这个字段加一下校验。

完整得多。


最后

ChatGPT、Codex 加完字段校验以后,接口没有报错,但数据库里的脏数据越来越多,通常说明:

系统只保证了“请求能成功”,却没有真正保证“数据是正确的”。

真正稳定的数据校验应该是:

前端提示 → 后端业务校验 → 数据库约束兜底。

尤其要警惕:

自动默认值、只做前端校验、只测正常参数

这三类问题。

因为脏数据最麻烦的地方,不是它写进去的那一刻。

而是:

等你几个月以后做统计、迁移或者新功能时,才发现整个系统已经被历史数据拖住了。


持续更新 ChatGPT、Codex、AI编程与后端工程实战内容,更多深度内容和稳定订阅渠道欢迎搜索关注「孤狼GPT」。

Logo

码道开发者社区,聚焦华为云码道 CodeArts 代码智能体,沉淀 Agent、Skill、鸿蒙开发实战内容,供开发者查阅资料、交流技术、分享工程实践

更多推荐