【问题标题】:Find all rows from a table which don't have references in any other tables from the same database从同一数据库的任何其他表中查找没有引用的表中的所有行
【发布时间】:2014-07-28 16:32:28
【问题描述】:

我正在使用外键和 InnoDB。 我有一个包含所有上传的图像数据的图像表。 每次我删除与图像表的连接时,我通常将图像表中的特定行标记为已删除。所以垃圾收集器通常会删除未使用的图像。

一次没有超过 1 个连接使用任何图像。

出于优化目的,我想在图像表(列“Id”)中找到所有没有连接的行。因为任何未使用的行都是僵尸行。

从我们失败的测试中,仍然有一些行没有连接。

示例图像表:

CREATE TABLE `image` (
  `Id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `FileName` varchar(255) NOT NULL,
  `Is_Deleted` tinyint(1) unsigned NOT NULL DEFAULT '0',
  `Disabled` tinyint(1) unsigned DEFAULT '0',
  PRIMARY KEY (`Id`),
) ENGINE=InnoDB AUTO_INCREMENT=816 DEFAULT CHARSET=utf8;

【问题讨论】:

    标签: mysql foreign-keys innodb


    【解决方案1】:

    您可以使用以下查询列出所有“僵尸”行:

    SELECT
      *
    FROM
      image
    WHERE
      image.`Id` NOT IN (SELECT table1.IdFK FROM table1 UNION 
                         SELECT table2.IdFK FROM table2 UNION
                         SELECT table3.IdFK FROM table3 ... )
    

    基本上,它会检查 image.Id 是否作为 FK 出现在另一个表中。您可以根据需要添加任意数量的UNION

    作为旁注,也许应该考虑添加完整性约束?

    【讨论】:

    • 我想避免这种情况,但现在我知道没有可靠的解决方案。问题是图像表需要首先与存储引擎(php)进行通信以进行物理删除,这是不可能的。问题是有数百个表集成了图像表......并且列名非常多样化。实际上这是 FK 的问题......所以我需要手动完成所有操作
    • 我只想进行一般性清理。也许我可以找到一种肮脏的方法来做到这一点,比如在图像表中找到所有具有 FK 的表和列,然后生成联合查询,然后标记所有以让图像垃圾收集器服务完成它的工作。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-18
    • 2015-07-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多