修改数据库所有表的存储引擎和字符集(排序规则)

<?php
$driver   = 'mysql';     // 数据库驱动
$host     = 'localhost'; // 主机地址
$dbname   = 'dbname';    // 数据库名
$port     = 3306;        // 服务端口号
$charset  = 'utf8mb4';   // 字符编码
$username = 'ZhangSan';  // 账号
$password = '*********'; // 密码

$options = [
    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
    PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
    PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES $charset",
    PDO::ATTR_EMULATE_PREPARES => false, // 禁用PHP模拟预处理(把预处理工作交给MySQL服务端)
];

$dsn = "$driver:host=$host;dbname=$dbname;port=$port;charset=$charset;";

try {
    $pdo = new PDO($dsn, $username, $password, $options);
} catch (PDOException $e) {
    exit('连接数据库失败:' . $e->getMessage());
}

const CONST_WRAP = '<br>' . PHP_EOL; // 换行

/**
 * 获取当前日期时间
 *
 * @return string 当前日期时间
 */
function datetime(): string
{
    return date('[Y-m-d H:i:s] ');
}

$character = 'utf8mb4'; // 字符集
$collate = 'utf8mb4_unicode_ci'; // 排序规则


//========== 修改数据库的字符集和排序规则·开始 ==========//
$sql = "ALTER DATABASE `$dbname` CHARACTER SET $character COLLATE $collate";
$success = true;

try {
    $query = $pdo->query($sql);
} catch (PDOException $e) {
    $success = false;
    unset($e);
}

if ($success) {
    echo datetime() . "修改数据库[$dbname]的字符集和排序规则为[$character.$collate]成功" . CONST_WRAP;
} else {
    $error = $pdo->errorInfo()[2];
    echo datetime() . "修改数据库[$dbname]的字符集和排序规则为[$character.$collate]失败:$error" . CONST_WRAP;
}
//========== 修改数据库的字符集和排序规则·结束 ==========//


// 查出数据库所有表
$sql = "SELECT `TABLE_NAME` FROM `information_schema`.`TABLES` WHERE `TABLE_SCHEMA` = '$dbname'";
$rows = $pdo->query($sql)->fetchAll();
$tables = array_column($rows, 'TABLE_NAME');

// 遍历所有表
foreach ($tables as $table) {
    //========== 修改数据表的存储引擎·开始 ==========//
    $engine = 'InnoDB'; // 存储引擎
    $sql = "ALTER TABLE `$table` ENGINE = $engine";
    $success = true;

    try {
        $query = $pdo->query($sql);
    } catch (PDOException $e) {
        $success = false;
        unset($e);
    }

    if ($success) {
        echo datetime() . "修改数据表[$table]的存储引擎为[$engine]成功" . CONST_WRAP;
    } else {
        $error = $pdo->errorInfo()[2];
        echo datetime() . "修改数据表[$table]的存储引擎为[$engine]失败:$error" . CONST_WRAP;
    }
    //========== 修改数据表的存储引擎·结束 ==========//


    //========== 修改数据表的字符集和排序规则·开始 ==========//
    $sql = "ALTER TABLE `$table` CONVERT TO CHARACTER SET $character COLLATE $collate";
    $success = true;

    try {
        $query = $pdo->query($sql);
    } catch (PDOException $e) {
        $success = false;
        unset($e);
    }

    if ($success) {
        echo datetime() . "修改数据表[$table]的字符集和排序规则为[$character.$collate]成功" . CONST_WRAP;
    } else {
        $error = $pdo->errorInfo()[2];
        echo datetime() . "修改数据表[$table]的字符集和排序规则为[$character.$collate]失败:$error" . CONST_WRAP;
    }
    //========== 修改数据表的字符集和排序规则·结束 ==========//


    //========== 修改字段(仅字符串类型字段)的字符集和排序规则·开始 ==========//
    $sql = "SHOW COLUMNS FROM `$table`"; // 查出数据表所有字段
    $fields = $pdo->query($sql)->fetchAll();
    foreach ($fields as $value) {
        $field = $value['Field'];
        $type = $value['Type']; // 字段的类型,示例:int(10) unsigned、varchar(256)、text

        // 无需判断字段是否为字符串类型,因为修改非字符串类型字段的字符集和排序规则会出错(抛出异常)
        $sql = "ALTER TABLE `$table` MODIFY `$field` $type CHARACTER SET $character COLLATE $collate";

        try {
            $query = $pdo->query($sql);
        } catch (PDOException) {
            continue;
        }

        echo datetime() . "修改字段[$table.$field]的字符集和排序规则为[$character.$collate]成功" . CONST_WRAP;
    }
    //========== 修改字段(仅字符串类型字段)的字符集和排序规则·结束 ==========//
}

echo datetime() . '操作执行完毕';


//========== 总结 ==========//
// 1、修改数据库操作比较耗时,如果网页访问出现超时可使用CLI模式执行脚本。

Copyright © 2024 码农人生. All Rights Reserved