A script to change all tables and fields to the utf-8-bin collation in MYSQL

后端 未结 16 1000
有刺的猬
有刺的猬 2020-12-04 06:24

Is there a SQL or PHP script that I can run that will change the default collation in all tables and fields in a database?

I can write one

16条回答
  •  情深已故
    2020-12-04 06:53

    I updated nlaq's answer to work with PHP7 and to correctly handle multicolumn indices, binary collated data (e.g. latin1_bin), etc., and cleaned up the code a bit. This is the only code I found/tried that successfully migrated my database from latin1 to utf8.

    Mysql Error: " . mysqli_error($conn) . "\n";
            echo "This query caused the above error: " . $query . "\n";
        }
        return $res;
    }
    
    function binary_typename($type) {
        $mysql_type_to_binary_type_map = array(
            "VARCHAR" => "VARBINARY",
            "CHAR" => "BINARY(1)",
            "TINYTEXT" => "TINYBLOB",
            "MEDIUMTEXT" => "MEDIUMBLOB",
            "LONGTEXT" => "LONGBLOB",
            "TEXT" => "BLOB"
        );
    
        $typename = "";
        if (preg_match("/^varchar\((\d+)\)$/i", $type, $mat))
            $typename = $mysql_type_to_binary_type_map["VARCHAR"] . "(" . (2*$mat[1]) . ")";
        else if (!strcasecmp($type, "CHAR"))
            $typename = $mysql_type_to_binary_type_map["CHAR"] . "(1)";
        else if (array_key_exists(strtoupper($type), $mysql_type_to_binary_type_map))
            $typename = $mysql_type_to_binary_type_map[strtoupper($type)];
        return $typename;
    }
    
    echo "
    ";
    
    // Connect to database
    $conn = mysqli_connect($host, $username, $password);
    mysqli_select_db($conn, $db);
    
    // Get list of tables
    $tabs = array();
    $query = "SHOW TABLES";
    $res = MySQLSafeQuery($conn, $query);
    while (($row = mysqli_fetch_row($res)) != null)
        $tabs[] = $row[0];
    
    // Now fix tables
    foreach ($tabs as $tab) {
        $res = MySQLSafeQuery($conn, "SHOW INDEX FROM `{$tab}`");
        $indicies = array();
    
        while (($row = mysqli_fetch_array($res)) != null) {
            if ($row[2] != "PRIMARY") {
                $append = true;
                foreach ($indicies as $index) {
                    if ($index["name"] == $row[2]) {
                        $index["col"][] = $row[4];
                        $append = false;
                    }
                }
                if($append)
                    $indicies[] = array("name" => $row[2], "unique" => !($row[1] == "1"), "col" => array($row[4]));
            }
        }
    
        foreach ($indicies as $index) {
            MySQLSafeQuery($conn, "ALTER TABLE `{$tab}` DROP INDEX `{$index["name"]}`");
            echo "Dropped index {$index["name"]}. Unique: {$index["unique"]}\n";
        }
    
        $res = MySQLSafeQuery($conn, "SHOW FULL COLUMNS FROM `{$tab}`");
        while (($row = mysqli_fetch_array($res)) != null) {
            $name = $row[0];
            $type = $row[1];
            $current_collation = $row[2];
            $target_collation_bak = $target_collation;
            if(!strcasecmp($current_collation, "latin1_bin"))
                $target_collation = $target_bin_collation;
            $set = false;
            $binary_typename = binary_typename($type);
            if ($binary_typename != "") {
                MySQLSafeQuery($conn, "ALTER TABLE `{$tab}` MODIFY `{$name}` {$binary_typename}");
                MySQLSafeQuery($conn, "ALTER TABLE `{$tab}` MODIFY `{$name}` {$type} CHARACTER SET '{$target_charset}' COLLATE '{$target_collation}'");
                $set = true;
                echo "Altered field {$name} on {$tab} from type {$type}\n";
            }
            $target_collation = $target_collation_bak;
        }
    
        // Rebuild indicies
        foreach ($indicies as $index) {
             // Handle multi-column indices
             $joined_col_str = "";
             foreach ($index["col"] as $col)
                 $joined_col_str = $joined_col_str . ", `" . $col . "`";
             $joined_col_str = substr($joined_col_str, 2);
    
             $query = "";
             if ($index["unique"])
                 $query = "CREATE UNIQUE INDEX `{$index["name"]}` ON `{$tab}` ({$joined_col_str})";
             else
                 $query = "CREATE INDEX `{$index["name"]}` ON `{$tab}` ({$joined_col_str})";
             MySQLSafeQuery($conn, $query);
    
            echo "Created index {$index["name"]} on {$tab}. Unique: {$index["unique"]}\n";
        }
    
        // Set default character set and collation for table
        MySQLSafeQuery($conn, "ALTER TABLE `{$tab}`  DEFAULT CHARACTER SET '{$target_charset}' COLLATE '{$target_collation}'");
    }
    
    // Set default character set and collation for database
    MySQLSafeQuery($conn, "ALTER DATABASE `{$db}` DEFAULT CHARACTER SET '{$target_charset}' COLLATE '{$target_collation}'");
    
    mysqli_close($conn);
    echo "
    "; ?>

提交回复
热议问题