mysql - 有条件地从 MySQL 数据库中删除标签

标签 mysql database-design

我的数据库中有以下三个表:

cases
  id   INT
  description   TEXT

tags
  id   INT
  name   TEXT

case_tag
  id   INT
  case_id   INT
  tag_id    INT

单个案例可以有任意数量的标签,并且一个标签可以属于任意数量的案例。

如果删除某个案例,我想删除 tags 表中链接到该案例的所有标签,前提是(且仅当)它们未链接到任何其他案例。我该如何实现这一目标?

最佳答案

假设您使用的是 InnoDB,请在 casecase_tag 之间创建一个 ON DELETE CASCADE 引用操作。然后,在删除所需的 case 后,相应的 case_tag 行将自动删除,剩下的就是简单地:

DELETE FROM tag WHERE tag_id NOT IN (SELECT tag_id FROM case_tag);

[SQL Fiddle]

如果需要,您甚至可以从触发器中执行此操作,但此方法更适合某种后台“清理”过程,因为它会清除所有多余的标签,而不仅仅是与最后一个相关的标签已删除案例

另一种方法是预先选择与要删除的案例相关的标签,然后尝试仅删除它们。


附带建议:

  • TEXT(BLOB 的一种形式)对于 tag.name 来说可能有点过分 - 请改用 VARCHAR。
  • 您可能不需要 surrogate key case_tag.id
  • 考虑在 case_tag {tag_id, case_id} 上添加索引(即与我的 SQL Fiddle 中的 PK 相反)。将 tag_id 置于索引的前沿对于在 tag_id 上强制执行 FK、选择给定标签的案例以及 DELETE 非常重要多于。我们包含 case_id 以使索引更有可能 cover查询,并且 case_id 无论如何都会包含在索引中,因为 clustered 中的二级索引表包含 PK 的副本。
  • 命名表时使用单数(或者至少不要混合使用复数和单数)。
  • 在 PK 字段名称中使用前缀。这有些争议,但根据我的经验,增加了 ER 模型、SQL 和 DAL 的可读性。 .

关于mysql - 有条件地从 MySQL 数据库中删除标签,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16795932/

相关文章:

database-design - 面向对象的数据库 - 为什么大多数公司不使用它们

sql - 如何在 Oracle 数据库 11g 中创建新模式/新用户?

mysql - 替换mysql中的CR字符

mysql - 调整MySQL排名查询

mysql - 如何按时间戳删除Mysql条目?

java - 数据存储是否适合存储小时类次?

database-design - 在表中表示多维数据的最佳实践是什么?

sql - 具有多个用户角色的数据库设计

php - 如何在单个sql查询中选择和求和

java - ANDROID 使用 AsyncTask MySQL 通过 JSON 更新 ListView