MySQL - 修复表



MySQL 修复表语句

数据库中的表可能会由于各种原因而损坏,例如硬件故障、软件错误或意外的服务器崩溃。在这种情况下,由于数据不一致或错误,我们将无法访问或操作这些表中的数据。

在这种情况下,为了修复这些损坏的表,我们使用 MySQL 的 **REPAIR TABLE** 语句。此语句仅适用于某些引擎,例如 MyISAM 等。

语法

以下是 MySQL REPAIR TABLE 语句的语法:

REPAIR [NO_WRITE_TO_BINLOG | LOCAL]
   TABLE tbl_name [, tbl_name] ...
   [QUICK] [EXTENDED] [USE_FRM]

示例

让我们首先使用以下查询创建一个名为 **CUSTOMERS** 的表:

CREATE TABLE CUSTOMERS (
   ID INT AUTO_INCREMENT,
   NAME VARCHAR(20) NOT NULL,
   AGE INT NOT NULL,
   ADDRESS CHAR (25),
   SALARY DECIMAL (18, 2),
   PRIMARY KEY (ID)
);

在这里,我们使用下面的 INSERT 语句将 7 条记录插入到上面创建的表中:

INSERT INTO CUSTOMERS (ID,NAME,AGE,ADDRESS,SALARY) VALUES 
(1, 'Ramesh', 32, 'Ahmedabad', 2000.00 ),
(2, 'Khilan', 25, 'Delhi', 1500.00 ),
(3, 'Kaushik', 23, 'Kota', 2000.00 ),
(4, 'Chaitali', 25, 'Mumbai', 6500.00 ),
(5, 'Hardik', 27, 'Bhopal', 8500.00 ),
(6, 'Komal', 22, 'Hyderabad', 4500.00 ),
(7, 'Muffy', 24, 'Indore', 10000.00 );

假设上面创建的表已损坏,我们使用 REPAIR TABLE 语句来修复它。

REPAIR TABLE CUSTOMERS;

上面的查询显示错误:**“表的存储引擎不支持修复”**,因为 REPAIR TABLE 语句不适用于默认的 InnoDB 引擎。

操作 消息类型 消息文本
tutorials.customers 修复 提示 表的存储引擎不支持修复

要修复表,我们需要将表的引擎更改为 **MyISAM**,因为它支持 REPAIR TABLE 语句。

ALTER TABLE CUSTOMERS ENGINE = MyISAM;

现在,要修复 CUSTOMERS 表,请执行以下查询:

REPAIR TABLE CUSTOMERS;

输出

我们可以在下面的输出中看到,它显示 **OK**,这表示 CUSTOMERS 表处于良好状态,没有问题或损坏。

操作 消息类型 消息文本
tutorials.customers 修复 状态 OK

修复多个表

在 MySQL 中,我们还可以修复多个表并使用 REPAIR TABLE 语句获取结果。为此,我们只需要列出要修复的表的名称,并用逗号分隔它们。

示例

让我们使用以下 CREATE TABLE 语句创建三个名为 **Test1**、**Test2** 和 **Test3** 的不同表:

CREATE TABLE Test1(ID INT, Name VARCHAR(255));
CREATE TABLE Test2(ID INT, Name VARCHAR(255));
CREATE TABLE Test3(ID INT, Name VARCHAR(255));

假设以上三个表已损坏。将这些表的引擎更改为 **MyISAM**,以便使用 REPAIR TABLE 语句修复它们:

ALTER TABLE Test1 ENGINE = MyISAM;
ALTER TABLE Test2 ENGINE = MyISAM;
ALTER TABLE Test3 ENGINE = MyISAM;

现在,要修复这些表,请执行以下查询:

REPAIR TABLE Test1, Test2, Test3;

正如我们在下面的输出中看到的,所有三个表都处于良好状态,没有问题或损坏。

操作 消息类型 消息文本
tutorials.test1 修复 状态 OK
tutorials.test2 修复 状态 OK
tutorials.test3 修复 状态 OK

修复表选项

REPAIR TABLE 有各种可选子句,例如 **QUICK**、**EXTENDED** 和 **USE_FRM** 子句。让我们逐一讨论它们并提供合适的示例。

QUICK 子句

QUICK 子句是默认子句,也是最常与 REPAIR TABLE 一起使用的子句。如果指定 QUICK 子句,MySQL 将在不重新创建表的情况下修复表。

示例

在以下示例中,我们使用 QUICK 子句和 REPAIR TABLE 语句来修复 CUSTOMERS 表。

REPAIR TABLE CUSTOMERS QUICK;
输出

执行上述查询将产生以下输出:

操作 消息类型 消息文本
tutorials.customers 修复 状态 OK

EXTENDED 子句

如果我们指定 *EXTENDED 子句*,MySQL 不仅会修复表,还会重建索引并优化表结构。

**注意:**与 QUICK 子句相比,EXTENDED 子句更耗时。

示例

在以下示例中,我们使用 EXTENDED 子句和 REPAIR TABLE 语句来修复 CUSTOMERS 表。

REPAIR TABLE CUSTOMERS EXTENDED;
输出

执行上述查询将产生以下输出:

操作 消息类型 消息文本
tutorials.customers 修复 状态 OK

USE_FRM 子句

如果 MYI 索引文件丢失,我们可以使用 *USE_FRM 子句*。如果提供此子句,将使用数据字典中的信息重新创建 .MYI 文件。

示例

在这里,我们使用 USE_FRM 子句和 REPAIR TABLE 语句来修复 CUSTOMERS 表。

REPAIR TABLE CUSTOMERS USE_FRM;
输出

执行上述查询将产生以下输出:

操作 消息类型 消息文本
tutorials.CUSTOMERS 修复 警告 已更改的行数从 0 变为 7
tutorials.customers 修复 状态 OK

使用客户端程序修复表

除了使用 MySQL 查询修复 MySQL 数据库中的表外,我们还可以使用客户端程序执行 REPAIR TABLE 操作。

语法

以下是各种编程语言中修复表的语法:

要在 MySQL 数据库中通过 PHP 程序修复表,我们需要使用 **mysqli** 函数 **query()** 执行 **Repair Table** 语句,如下所示:

$sql="Repair TABLE table_names";
$mysqli->query($sql);

要在 MySQL 数据库中通过 Node.js 程序修复表,我们需要使用 **mysql2** 库的 **query()** 函数执行 **Repair Table** 语句,如下所示:

sql=" REPAIR [NO_WRITE_TO_BINLOG | LOCAL] TABLE tbl_name [, tbl_name] ...
   [QUICK] [EXTENDED] [USE_FRM]";
con.query(sql);

要在 MySQL 数据库中通过 Java 程序修复表,我们需要使用 **JDBC** 函数 **executeUpdate()** 执行 **Repair Table** 语句,如下所示:

String sql="Repair TABLE table_names";
statement.executeUpdate(sql);

要在 MySQL 数据库中通过 Python 程序修复表,我们需要使用 MySQL **Connector/Python** 的 **execute()** 函数执行 **Repair Table** 语句,如下所示:

sql="REPAIR TABLE table_name";
cursorObj.execute(sql);

示例

以下是程序:

$dbhost = 'localhost';
$dbuser = 'root';
$dbpass = 'password';
$dbname = 'TUTORIALS';
$mysqli = new mysqli($dbhost, $dbuser, $dbpass, $dbname);

if ($mysqli->connect_errno) {
    printf("Connect failed: %s
", $mysqli->connect_error); exit(); } // printf('Connected successfully.
'); $sql = " REPAIR TABLE SalesSummary "; if ($mysqli->query($sql)) { printf(" Table repair successfully.
"); } if ($mysqli->errno) { printf("table could not be repaired .
", $mysqli->error); } $mysqli->close();

输出

获得的输出如下:

Table repair successfully.
var mysql = require('mysql2');
var con = mysql.createConnection({
    host: "localhost",
    user: "root",
    password: "Nr5a0204@123"
});

  //Connecting to MySQL
  con.connect(function (err) {
  if (err) throw err;
  console.log("Connected!");
  console.log("--------------------------");

  sql = "Create Database TUTORIALS"
  con.query(sql);

  sql = "USE TUTORIALS"
  con.query(sql);

  sql = "CREATE TABLE sales(ID INT, ProductName VARCHAR(255), CustomerName VARCHAR(255), DispatchDate date, DeliveryTime time, Price INT, Location VARCHAR(255));"
  con.query(sql);

  sql = "insert into sales values(1, 'Key-Board', 'Raja', DATE('2019-09-01'), TIME('11:00:00'), 7000, 'Hyderabad'),(2, 'Earphones', 'Roja', DATE('2019-05-01'), TIME('11:00:00'), 2000, 'Vishakhapatnam'),(3, 'Mouse', 'Puja', DATE('2019-03-01'), TIME('10:59:59'), 3000, 'Vijayawada'),(4, 'Mobile', 'Vanaja', DATE('2019-03-01'), TIME('10:10:52'), 9000, 'Chennai'),(5, 'Headset', 'Jalaja', DATE('2019-04-06'), TIME('11:08:59'), 6000, 'Goa');"
  con.query(sql);

  sql = "ALTER TABLE Sales ENGINE = MyISAM;"
  con.query(sql);

  sql = "REPAIR TABLE Sales;"
  con.query(sql, function(err, result){
    if (err) throw err
    console.log(result);
  });
});

输出

生成的输出如下:

Connected!
--------------------------
[
  {
    Table: 'tutorials.sales',
    Op: 'repair',
    Msg_type: 'status',
    Msg_text: 'OK'
  }
]
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;

public class RepairTable{
        public static void main(String[] args){
            String url = "jdbc:mysql://127.0.0.1:3306/TUTORIALS";
            String username = "root";
            String password = "password";
            try{
                Class.forName("com.mysql.cj.jdbc.Driver");
                Connection connection = DriverManager.getConnection(url, username, password);
                Statement statement = connection.createStatement();
                System.out.println("Connected successfully...!");

                //Repair tables...!
                String sql = "REPAIR TABLE customers";
                statement.executeUpdate(sql);
                System.out.println("Table repaired successfully...!");

                connection.close();
            }
            catch(Exception e){
                System.out.println(e);
            }
        }
}

输出

获得的输出如下所示:

Connected successfully...!
Table repaired successfully...!
import mysql.connector
#establishing the connection
connection = mysql.connector.connect(
    host='localhost',
    user='root',
    password='password',
    database='tut'
)
table_name = 'tutorials_tbl_temp'
#Creating a cursor object 
cursorObj = connection.cursor()
repair_table_query = f"REPAIR TABLE {table_name}"
cursorObj.execute(repair_table_query)
print(f"Table '{table_name}' is repaired successfully.")
# Fetch and consume any remaining results from the cursor
# ensuring that there are no unread results before closing the cursor.
for _ in cursorObj:
    pass
cursorObj.close()
connection.close()

输出

以下是上述代码的输出:

Table 'tutorials_tbl_temp' is repaired successfully.
广告