codeigniter 的 delete() 方法不支持 like 条件,需先用 like() 查询 id 再通过 where_in() 批量删除,或使用带参数的原生 sql;关联数据需手动清理,并推荐封装为事务、专用命令和配置驱动。

CodeIgniter 本身不提供“模糊匹配后直接删除”的内置方法,delete() 不支持 like 条件。想按模糊条件清理冗余数据(比如删掉邮箱含 @test.com 的测试用户、标题含 [DEPRECATED] 的旧资讯),必须组合使用查询与删除逻辑,不能一步到位。
用 where + like 先查再删(推荐,安全可控)
这是最稳妥的方式:先用 like() 找出目标记录 ID,再用 where_in() 批量删除。避免全表扫描锁表,也便于加日志和分批处理。
- 在 Model 中写一个清理方法:
class Cleanup_model extends CI_Model {
public function delete_test_users_by_domain($domain = 'test.com') {
$this->db->select('id');
$this->db->from('users');
$this->db->like('email', $domain, 'both'); // 匹配任意位置
$query = $this->db->get();
$ids = $query->result_column('id'); // CodeIgniter 4 支持;CI3 可用 array_column($query->result_array(), 'id')
if (empty($ids)) return 0;
// 分批删除,每批 500 条防超时
$chunks = array_chunk($ids, 500);
$total = 0;
foreach ($chunks as $chunk) {
$this->db->where_in('id', $chunk);
$total += $this->db->delete('users');
}
return $total;
}
}
- 调用示例:
$this->cleanup_model->delete_test_users_by_domain('dev.local'); - 优势:可加事务、可记录日志、可限流、可中断重试。
用原生 SQL 执行模糊删除(高效但需谨慎)
如果确认数据量不大、环境可控(如本地或预发库),可用原生语句提升效率。注意:务必提前备份,且禁止在生产环境无防护执行。
- CI3/CI4 均支持:
$sql = "DELETE FROM users WHERE email LIKE ?";
$this->db->query($sql, ['%@staging.%']);
- MySQL 中
LIKE '%@staging.%'会走全表扫描,大表慎用;建议先加索引(如对 email 建前缀索引)或改用正则(REGEXP)提高精度。 - 删除前强烈建议先用
SELECT COUNT(*)预估影响行数。
关联表联动清理(避免脏数据)
删除主表记录时,若存在外键关联(如用户 → 订单、评论),需同步清理或设为 NULL。CodeIgniter 不自动级联,得手动处理。
- 例如:删掉旧用户后,清空其评论:
$user_ids = $this->db->select('id')->from('users')->like('username', 'demo_', 'after')->get()->result_column('id');
if (!empty($user_ids)) {
$this->db->where_in('user_id', $user_ids);
$this->db->delete('comments');
}
- 更健壮的做法是封装成事务:
-
$this->db->trans_start();开启事务,$this->db->trans_complete();提交或回滚。
自动化与可维护性建议
这类操作不应散落在控制器里,也不该写进迁移文件(迁移只管结构)。推荐统一归入:
- 专用的清理命令:CI4 可写
php spark cleanup:staging-data;CI3 可写 CLI 脚本放在tools/目录下。 - 配置驱动:把模糊规则(如要删的域名列表、关键词模板)抽到 config 文件中,方便不同环境切换。
- 加审计日志:每次执行记录时间、条件、影响行数,便于追溯。











