【问题标题】:How to delete all tables that have 1-2 rows如何删除所有有 1-2 行的表
【发布时间】:2016-09-21 13:34:08
【问题描述】:

我有一个超过 60k 表的数据库,我想删除所有包含 1 或 2 行的表。

【问题讨论】:

  • 删除所有表还是删除所有表?
  • 您能分享一下您的尝试吗?
  • @RahulTripathi 不是一回事吗?据我所知,当我需要删除/删除表时,我需要使用 DROP
  • 这表明了一个可怕的数据模型。通常一个表包含一个实体,例如用户、国家、语言或产品。一个人永远不会删除语言表,因为它包含不超过两种语言。你只会删除一个表,因为你不需要它,例如一些记录表,这仍然是一种极其罕见的情况。因此,与其根据行数删除某些表,不如重新考虑完整的数据库设计。
  • 这似乎没有什么不同。如果是标签,那么您应该需要一个标签表来存储所有用户的标签。

标签: mysql sql


【解决方案1】:
  • 使用 MySQL-GUI,按行数排序并删除所有 1-2 行的表。就像删除 Windows 文件夹中的文件一样简单。这 大约需要 10 秒 + 排序和删除时间

  • 从 information_schemas 中选择具有 1-2 行的表的表名,加载到 excel 文件中并构建您的 drop 语句。大约需要 2-5 分钟 + 下车时间

  • 构建一个存储过程,该过程使用游标将所有相关的表名解析为您的 drop 语句的变量(如 Hansa 提到的)。如果您想不时重复您的过程,这是有道理的。初学者大约需要 1-12 小时(取决于知识水平)+ 下降时间

由于登录 SO 可能比解决方案 1 花费更多时间, 我会推荐这个解决方案。

如果您想花更多时间,以下查询将显示 1-2 行表的所有表名:

SELECT table_schema, table_name From information_schema.tables
WHERE table_schema='your_schema' # use your table_schema here
AND table_rows BETWEEN 1 and 2 ;

【讨论】:

    【解决方案2】:

    除非您使用存储过程(见下文),否则您可能无法使用 1 个 SQL 语句执行此操作。 您需要使用以下语句选择 MySQL 中的所有表(例如 Java 和 JDBC):

    select TABLE_NAME from INFORMATION_SCHEMA.TABLES where TABLE_ROWS <= 2 AND TABLE_ROWS >= 1
    

    然后您可以使用编程语言中的结果为循环中的每个结果记录发出 drop 语句:

    drop table <tablename>
    

    使用存储过程执行此操作(即没有编程语言) 请参阅此页面上的第三条评论:MySQL Reference Drop Table。 当然,您需要根据自己的需要进行调整,因为此示例不按行号而是按名称选择表。

    【讨论】:

      【解决方案3】:

      您可以在 SQL Server 2012 中使用以下代码。它将删除所有 row_count 小于 3 的表。

      USE [YourDB]
      GO
      DECLARE @Max int, @Count int,@Table_Name Varchar(20)
      SET @Max =0
      IF OBJECT_ID('tempdb..#temp') IS NOT NULL
      DROP TABLE #temp
      CREATE TABLE #temp 
          (
          table_name sysname ,
          row_count INT,
          reserved_size VARCHAR(50),
          data_size VARCHAR(50),
          index_size VARCHAR(50),
          unused_size VARCHAR(50)
          )
      IF OBJECT_ID('tempdb..#temp1') IS NOT NULL
      DROP TABLE #temp1
      CREATE TABLE #temp1
          (
          ID int IDENTITY(1,1),
          table_name sysname ,
          row_count INT
          )
      SET NOCOUNT ON
          INSERT #temp
          EXEC sp_msforeachtable 'sp_spaceused ''?'''
          INSERT INTO #temp1
              SELECT a.table_name,
              a.row_count
              FROM #temp a
              INNER JOIN information_schema.columns b
              ON a.table_name collate database_default
              = b.table_name collate database_default
              GROUP BY a.table_name, a.row_count
              HAVING a.row_count <3
      
      
          SET @Count =(SELECT COUNT(*) FROM #temp1)
      
          WHILE @Count > @Max
          BEGIN
              SET @Max = @Max +1
              SET @Table_Name = (SELECT table_name FROM #temp1 WHERE ID = @Max)
              EXEC('DROP TABLE ' +@Table_Name)
          END
      

      【讨论】:

        【解决方案4】:

        你可以试试这个。 首先从数据库中获取所有表名。 获取所有表名后,将它们放入一个数组并执行一个 foreach 循环,检查每个表的行数,如下所示

        $tables = array();
        
        foreach ($tables as $table_name){
            $query    = "select * from '$table_name'";
            $result   = mysqli_query($dbCon, $query);
            $num_rows = mysql_num_rows($result);
        
            if($num_rows < 3){
                $delete = "drop table $table_name";
                $res_del = mysqli_query($dbCon, $delete);
                echo $table_name." Deleted";
            }
        }
        

        【讨论】:

          【解决方案5】:

          我会在一些应用程序端逻辑中使用您选择的编程语言(提供 mysql API)。

          1. 获取所有表名,描述here,按表名分组 例如这可能看起来像:

            SELECT COUNT(table_rows), table_name FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = '{your_db}' GROUP BY table_name;

          (这个没有经过测试,只是给大家一个基本的思路……)

          1. 对行数为 2 或更低的表执行删除语句。一旦你用你的编程语言得到结果应该是一件容易的事(顺便说一句,删除它们的 SQL 语句是“DROP TABLE”)

          注意:我认为也应该可以使用 SQL 游标,但正如我所说,我更喜欢上述解决方案。

          【讨论】:

            猜你喜欢
            • 2015-03-26
            • 2012-03-15
            • 2012-11-19
            • 1970-01-01
            • 2014-09-04
            • 1970-01-01
            • 2020-02-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多