首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 綜合知識

PHP 更新多对多中间表数据的两种策略:全量替换 vs 增量差异

     編輯:PHP 綜合知識

多对多关系(如 课程-课时、用户-角色)通过中间表维护。更新时面临「如何同步前端提交的 ID 列表与数据库现状」的问题。本文对比「全量删除重建」与「增量差异同步」两种方案,给出代码实现与选型建议。

场景设定

  • 主表:classes(课程)
  • 从表:lessons(课时)
  • 中间表:lesson_classes (class_id, lesson_id)
  • 前端提交:$lesson_ids = [1, 3, 5, 7](新关联列表)

方案一:全量删除重建(简单但有风险)

classes->classEdit($id, $data); // 更新主表
if ($res) {
    // 1. 删除所有旧关联
    $bool = $this->lesson_classes->lessonClassesDel($id);
    if ($bool) {
        // 2. 循环插入新关联
        foreach ($lesson_ids as $val) {
            $arr = ['class_id' => $id, 'lesson_id' => $val];
            $this->lesson_classes->lessonClassesAdd($arr);
        }
    }
    $this->show_tips('操作成功!');
} else {
    $this->show_tips('操作失败!');
}
?>

弊端:并发下「删了没加上」导致数据丢失;大批量删除触发锁升级、主从延迟、外键级联风险;无法审计变更历史。

方案二:增量差异同步(推荐,安全高效)

lesson_classes->getByClassId($id); // 返回 [['lesson_id'=>1], ['lesson_id'=>2]...]
$arr_old = array_column($old_rows, 'lesson_id');     // [1, 2]

// 2. 计算差异集
$arr_new = $lesson_ids;                               // [1, 3, 5, 7]
$intersect = array_intersect($arr_old, $arr_new);     // 交集:[1] 保留不动
$result_del = array_diff($arr_old, $intersect);       // 旧有新无:[2] 删除
$result_add = array_diff($arr_new, $intersect);       // 新有旧无:[3,5,7] 新增

// 3. 执行新增
$bool_add = true;
if ($result_add) {
    foreach ($result_add as $val) {
        $bool_add &= $this->lesson_classes->lessonClassesAdd(['class_id' => $id, 'lesson_id' => $val]);
    }
}

// 4. 执行删除
$bool_del = true;
if ($result_del) {
    foreach ($result_del as $val) {
        $bool_del &= $this->lesson_classes->lessonClassesDel($id, $val);
    }
}

if ($bool_add && $bool_del) {
    $this->show_tips('操作成功!');
} else {
    $this->show_tips('操作失败!');
}
?>

方案对比表

维度全量重建增量差异
代码复杂度低中
数据安全性低(删除窗口期风险)高(仅操作变更行)
并发性能差(全表锁/大量行锁)优(精准行锁)
审计/日志难(全删全增)易(明确增删记录)
适用场景数据量极小、低并发、无审计需求通用生产环境、高并发、需审计

进阶:事务包裹保证原子性

beginTransaction();
try {
    // 增删操作...
    $pdo->commit();
} catch (Exception $e) {
    $pdo->rollBack();
    throw $e;
}
?>

增量差异同步是中间表更新的标准模式,配合事务与乐观锁,可构建健壮的多对多关系管理模块。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved