CodeIgniter 4中如何用is_unique实现两列联合唯一性校验
多字段组合唯一校验实现方案
is_unique规则完全支持Day、Timing两列的联合唯一校验场景,不需要额外手写全表重复查询逻辑,规则本身就支持追加多字段匹配条件。
具体实现方式
1. 新增记录场景的校验规则写法
绝大多数带is_unique校验规则的后端框架(比如CodeIgniter、ThinkPHP等),都支持给唯一规则追加额外的等值查询条件,你要实现“星期+时段”组合不重复,只要在校验Timing字段的is_unique规则里,把Day作为联合匹配字段传入即可。
以CodeIgniter框架的校验规则写法为例:
// 定义校验规则,schedules是你的日程表名 $validation->setRules([ 'Day' => 'required', 'Timing' => [ 'label' => '时段', // 核心规则释义:在schedules表中查询,是否存在Timing值与本次提交值相同、且Day值与本次提交Day值相同的记录,存在则判定重复 'rules' => 'required|is_unique[schedules.Timing,Day,{Day}]' ] ]);
如果是Laravel这类框架,唯一规则的写法逻辑完全一致,只是参数格式略有区别,核心都是给唯一校验追加Day字段的等值匹配条件,实现两个字段的组合去重。
2. 编辑更新场景的规则适配
编辑已有日程记录的时候,需要排除当前正在编辑的记录本身,否则校验时会把本条旧数据查出来,误判为重复。这时候只要在原有规则基础上,追加主键排除条件即可:
// 假设日程表主键为id,当前正在编辑的记录ID存储在$currentId变量中 $validation->setRules([ 'Timing' => [ 'rules' => "required|is_unique[schedules.Timing,Day,{Day},id,{$currentId}]" ] ]);
上述规则的判断逻辑为:除了id等于当前编辑记录ID的行之外,其余行中如果存在Day+Timing组合和提交值一致的记录,才判定为重复。
3. 数据库层兜底(必做)
不要只依赖代码层的校验,高并发场景下(比如多个用户同时提交同一时段的日程),代码层校验可能因为请求执行的时间差出现漏判,一定要给数据库表加联合唯一索引做兜底:
-- 给Day和Timing字段加联合唯一索引 ALTER TABLE schedules ADD UNIQUE INDEX `idx_day_timing` (`Day`, `Timing`);
加完索引后就算代码层校验漏过了重复请求,数据库也会直接抛出重复键错误,你只要在代码里捕获该异常,返回“所选星期对应的时段已被配置,请更换时段”的友好提示即可,从存储层彻底杜绝重复数据。
内容的提问来源于stack exchange,提问作者Jitendra Pawar
相关产品推荐
相关产品推荐

