【问题标题】:MySQL delete and remove from many-to-many table in one transactionMySQL 在一个事务中从多对多表中删除和删除
【发布时间】:2015-04-24 20:24:27
【问题描述】:

是否可以从关联表中删除(多对多)并在同一事务中插入同一行?

这是我的关联表:

CREATE TABLE image_tag (
  imageid bigint(19) NOT NULL, 
  tagid   bigint(19) NOT NULL, 
  PRIMARY KEY (imageid, tagid));
ALTER TABLE image_tag ADD INDEX FKimage_tag587679 (tagid), ADD CONSTRAINT  FKimage_tag587679 FOREIGN KEY (tagid) REFERENCES tag (id);
ALTER TABLE image_tag ADD INDEX FKimage_tag426448 (imageid), ADD CONSTRAINT FKimage_tag426448 FOREIGN KEY (imageid) REFERENCES image (id);

当我在一个事务中创建新图像并插入图像时,插入标签并插入 image_tag,一切正常。

当我想更新Image和I时出现问题:

  • 开始交易
  • 使用给定的 $id 更新图像
  • 调用:DELETE FROM image_tag WHERE imageid = $id
  • 检查 image_tag 对于 imageid = $id 是否为空(并且是)
  • 检索新标签的 ID(其中一些保持不变)
  • 尝试插入 image_tag ...但我收到异常

例外:

Cannot add or update a child row: a foreign key constraint fails (`mydatabase`.`image_tag`, CONSTRAINT `FKimage_tag426448` FOREIGN KEY  (`imageid`) REFERENCES `image` (`id`))  

数据:

Original data: (194, 123), (194, 225), (194, 291)
New data: (194, 123), (194, 225), (194, 65)

源代码(PHP):

if ($editation) {
  if ($values->image->isOk()) {
    $url = $img->load($values->id)->getUrl();
    $values->image->move($this->wwwDir . "/" . $url);
  } else {
    $url = null;
  }      
  $img->update($values->name, $values->descr, $url, null, $featured);
} else {
  $uname = $img->createUniqueName($values->name);
  $url = ImageManager::PATH . "/" . $uname . ".svg";
  $values->image->move($this->wwwDir . "/" . $url);
  $img->create($userId, $values->name, $url, $values->descr, null, $featured);      
}

// Delete old image-tag associations if any
$this->db->query('DELETE FROM image_tag WHERE imageid = %i', $img->getId());

// Save tags and assign them to image
$tagIds = $this->tagManager->saveTags($values->tags);
$assoc = (new Dao\ImageTag())->setDb($this->db);
//throw new \Exception(implode(",", $tagIds));
foreach ($tagIds as $tagId) {     
  // EXCEPTION IS THROWED HERE (but only after editation)
  $assoc->create($img->getId(), $tagId);      
}

【问题讨论】:

  • 您能否再展示一些示例数据并解释一下为什么需要删除?从您的原始数据到新数据,看起来唯一变化的行是最后一行,我不确定您为什么不能只运行 update 查询?
  • 因为我不想提供额外的逻辑——我应该保留哪些标签,哪些不应该保留——我只是简单地删除所有标签,然后添加所有当前标签,不管哪些是相同的,哪些不是。您认为这种方法不好吗?
  • 嗯,这当然很危险,除非你把它全部包装在一个事务中。如果删除有效但插入失败会发生什么?您可能会丢失大量数据。另外,我不确定您是否可以在同一个查询中运行删除和插入。您是否已经坚决反对更新?如果可能的话,我认为这可能是一种更好的方法。

标签: php mysql transactions many-to-many model-associations


【解决方案1】:

您不尝试使用无效的 id 更新您的 image_tag 吗? ..null、0、-1 还是别的什么?

查看您的代码。我想 $img 和 $values->image 不一样,但是只有在提供 $values->image 时才加载 $img 。但是,您每次都尝试更新 image_tag。

【讨论】:

    猜你喜欢
    • 2014-02-26
    • 2023-03-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多