TL; DR;
当ids未知时,是否有更快的方式更新m:m记录逐个循环。
这是关于使用标签。
在前端,我有表单使用基于文本的输入来列出和更新标签。
提交表单时,用户记录需要通过删除和创建m:m表中的记录来更新标记
有多种标记类型,因此有多个标记输入字段,但都存储在同一个表中。
因为当前系统使用标签作为字符串,一旦表单将输入数据传递回服务器,它就是一个CSV字符串。
计划(计划,因为我从存储作为字符串更新)是
$tags = implode(',', array_merge($tagset1, $tagset2));
$update_tags = explode(',',$tags);
user_tag
table $update_tags
作为$tag_name
$tag_name
user_tag
表中,用于user_id和tag_id组合过去我发现了删除发生的问题,但是一些未处理的错误导致更新无法通过。我怀疑通过实施回滚可以减轻这种情况。
虽然双方用于更新的标签数量相当低(用户将少于15个,总共少于1000个标签)但我担心这个循环方面,因为过去的经验非常好指示循环中的sql是一个很好的避免。
答案 0 :(得分:0)
这就是我最终做的......
它与我的意图有点不同。
我将字符串分解并与视图结果(作为数组)进行比较并执行两个array_diff
操作,一个用于查找删除操作,另一个用于查找插入操作。
每种操作类型都有一个查询,查找用户标签,插入用户标签,删除用户标签。
唯一的重复是根据标记名称查找标记ID的查询,在这种情况下它无论如何都不会循环。
public function update_tags($user_id, $tags)
{
// convert tags string to array
$update_tags = explode(',',$tags);
// find user's tags
$user_tag_view_reslt = $user_tag_view->find(array("user_id = ?", $user_id));
// reduce to array with tag names only
$user_tag_view_reslt = array_column( $user_tag_view_reslt, 'tag_name');
$remove_tags = array_diff($user_tag_view_reslt, $update_tags);
$insert_tags = array_diff($update_tags, $user_tag_view_reslt);
$this->remove_user_tags($user_id, $remove_tags);
$this->insert_user_tags($user_id, $insert_tags);
}
public function remove_user_tags($user_id, $tags_array)
{
$tags_string = "'".implode("','",$tags_array)."'";
$tag_model = new \Model\Tag();
$rows = $db->exec("SELECT tag_id FROM tag WHERE tag_name in($tags_string) ");
$delete_tag_ids = implode(',',array_column($rows,'tag_id'));
// check if there are any rows to insert before doing so
if($delete_tag_ids != ''){
$exec = $db->exec("DELETE FROM `user_tag` WHERE user_id = $user_id AND tag_id in ($delete_tag_ids);");
}
}
public function insert_user_tags($user_id, $tags_array)
{
$tags_string = "'".implode("','",$tags_array)."'";
$tag_model = new \Model\Tag();
$rows = $db->exec("SELECT tag_id FROM tag WHERE tag_name in($tags_string) ");
$insert_tag_ids = implode(',',array_column($rows,'tag_id'));
$sql_vals = array();
foreach($rows as $row){
array_push($sql_vals,"($user_id, ".$row['tag_id']." )");
}
$sql_vals_str = implode($sql_vals,",");
// check if there are any rows to insert before doing so
if($insert_tag_ids != ''){
$exec = $db->exec("INSERT INTO `user_tag` (user_id, tag_id) VALUES $sql_vals_str;");
}
}
需要PHP 5.5或更高版本(由于array_column),它也无法调整和适应未显示代码的模型