【问题标题】:Deleting rows in linked MySQL tables and decrementing count in another table删除链接的 MySQL 表中的行并减少另一个表中的计数
【发布时间】:2012-11-30 18:24:52
【问题描述】:

我正在尝试创建(基于 java 的)消息传递 webapp。消息使用 MySQL 使用三个表进行存储:

  • 'messages':有两列,一个 id 主键('idmessage')和消息('message')。
  • 'tags':用户还输入与他们的消息相关联的标签。这有两列 - 标签(也是主键)和计数('count')。
  • 'message_tag_link':由于消息和标签之间存在多对一的关系,因此我有第三个链接表。这有两列,消息的外键 ('fk_idmessage') 和标签表的 id ('fk_tag')。

将消息插入数据库工作正常。我在 Java 中使用以下几行:

pst1 = connection.prepareStatement("INSERT INTO messages(message) VALUES (?)");
pst2 = connection.prepareStatement("INSERT INTO tags(tag,count) VALUES (?,1) ON     DUPLICATE KEY UPDATE count = count + 1");
pst3 = connection.prepareStatement("INSERT INTO message_tag_link(fk_idmessage,fk_tag) VALUES (? , ?)");

可以看出,每次创建重复的标签条目时,pst2 中的“计数”都会增加。 我正在尝试弄清楚如何完全删除一条消息。我在链接表的列中的外键上有on delete cascade 描述,但不知道下一步该做什么。对于给定的 'messageid',我需要:

  1. 删除“消息”表中的一行
  2. 删除“message_tag_link”表中的关联行
  3. 如果消息删除成功,则减少“tags”表中的计数值,或者如果计数变为零,则完全删除该行。

是否可以在 MySQL 中使用 Java PreparedStatement 完成所有这些操作?任何指针都非常感谢。我是一个完全的 MySQL 新手,所以请善待!

【问题讨论】:

  • 存储计数是否有原因?您可以只使用附加的消息数。
  • ...也许使用VIEW 来计算标签计数。
  • @Jim 是的。我可以看到没有计数列的解决方案可能有效。我不清楚的是如果没有此列,当您从“消息”和链接表中删除行时,您可能会在标签列中留下不再对应于消息的行(即计数为零的情况)一个标签)。这就是为什么我认为 count 列将是解决这个问题的一种很好且快速的方法 - 但不知道如何使用它,因此我的问题!

标签: java mysql prepared-statement sql-delete


【解决方案1】:

这些查询应该满足您的需求。 ?在每个查询中应该是要删除的消息 id

//Update count
UPDATE tags SET `count` = `count` - 1 WHERE tag_id IN (SELECT fk_tag FROM message_tag_link WHERE fk_idMessage = ?);
//Remove link
DELETE FROM message_tag_link WHERE fk_idmessage = ?;
DELETE FROM messages WHERE id = ?;
//Remove unused tags
DELETE FROM tags WHERE `count` = 0;

正如您所发现的那样,保持计数可能很烦人。更好的是使用链接本身。

SELECT COUNT(fk_idmessage) AS msgcount FROM message_tag_link WHERE fk_tag = ?;

您还可以添加一个 CASCADE,以便在删除消息时标签链接也会被删除(请参阅here)。但是要小心这种行为)。

此解决方案仍然会留下没有消息的标签,但您可以使用查询删除这些标签:

DELETE FROM tags t WHERE NOT EXISTS (SELECT 1 FROM nessage_tag_link WHERE t.tag_id = fk_tag)

【讨论】:

  • "COUNT" 是 MySQL 关键字。我建议使用反引号:UPDATE `tags` SET `count` = `count` - 1... 等
  • @Anton 很好发现。已在适当的地方转义了计数字段。
  • 甜蜜。我选择了更详细的顶部(并保留了我的计数列),它奏效了。
猜你喜欢
  • 2016-07-26
  • 1970-01-01
  • 1970-01-01
  • 2018-10-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多