在MYSQL中将所有表和字段更改为utf-8-bin排序规则的脚本

56 php mysql sql collation utf-8

是否有可以运行的脚本SQLPHP脚本将更改数据库中所有表和字段的默认排序规则?

我可以自己写一个,但我认为这应该是像这样的网站上可以随时使用的东西.如果我在某人发帖之前能够拿出一个,我会自己发布.

Dav*_*tom 85

可以在一个命令中完成(而不是148个PHP):

mysql --database=dbname -B -N -e "SHOW TABLES" \
| awk '{print "SET foreign_key_checks = 0; ALTER TABLE", $1, "CONVERT TO CHARACTER SET utf8 COLLATE utf8_general_ci; SET foreign_key_checks = 1; "}' \
| mysql --database=dbname &
Run Code Online (Sandbox Code Playgroud)

你必须喜欢命令行...(你可能需要使用--user--password选项mysql).

编辑:避免外键问题,添加SET foreign_key_checks = 0;SET foreign_key_checks = 1;

  • @DavidWinterbottom对于这个答案你应该在你的家乡为你的荣誉竖立一尊雕像. (3认同)
  • 您确实需要意识到这种方法可能会导致问题。一方面,在运行此命令后,任何 latin1 列都是 TEXT 现在将是 MEDIUMTEXT。因此,您可能会出现静默数据丢失/截断。有关更多详细信息,请参阅:http://codex.wordpress.org/Converting_Database_Character_Sets 和 http://www.mysqlperformanceblog.com/2009/03/17/converting-character-sets/。 (2认同)
  • 我得到答案的命令行的确切代码:`mysql -u root -ppassword --database = dbname -B -N -e“ SHOW TABLES” | awk'{print“ SET foreign_key_checks = 0; ALTER TABLE”,$ 1,“转换为字符SET utf8 COLLATE utf8_general_ci; SET foreign_key_checks = 1;”}“ | mysql -u root -ppassword --database = dbname&` (2认同)

小智 39

我认为在PhpMyAdmin中运行两步很容易.
步骤1:

SELECT CONCAT('ALTER TABLE `', t.`TABLE_SCHEMA`, '`.`', t.`TABLE_NAME`,
 '` CONVERT TO CHARACTER SET utf8 COLLATE utf8_general_ci;') as stmt 
FROM `information_schema`.`TABLES` t
WHERE 1
AND t.`TABLE_SCHEMA` = 'database_name'
ORDER BY 1
Run Code Online (Sandbox Code Playgroud)

第2步:
此查询将输出一个查询列表,每个表一个.您必须复制查询列表,并将它们粘贴到命令行或PhpMyAdmin的SQL选项卡以进行更改.


小智 27

好的,我写了这个,考虑到这个帖子中的内容.感谢您的帮助,我希望这个脚本可以帮助其他人.我对它的使用没有任何保证,所以请在运行之前备份.它应该适用于所有数据库; 它本身很好用.

编辑:添加了顶部的变量,其中charset/collat​​e将转换为.EDIT2:更改数据库和表的默认字符集/整理

<?php

function MysqlError()
{
    if (mysql_errno())
    {
        echo "<b>Mysql Error: " . mysql_error() . "</b>\n";
    }
}

$username = "root";
$password = "";
$db = "database";
$host = "localhost";

$target_charset = "utf8";
$target_collate = "utf8_general_ci";

echo "<pre>";

$conn = mysql_connect($host, $username, $password);
mysql_select_db($db, $conn);

$tabs = array();
$res = mysql_query("SHOW TABLES");
MysqlError();
while (($row = mysql_fetch_row($res)) != null)
{
    $tabs[] = $row[0];
}

// now, fix tables
foreach ($tabs as $tab)
{
    $res = mysql_query("show index from {$tab}");
    MysqlError();
    $indicies = array();

    while (($row = mysql_fetch_array($res)) != null)
    {
        if ($row[2] != "PRIMARY")
        {
            $indicies[] = array("name" => $row[2], "unique" => !($row[1] == "1"), "col" => $row[4]);
            mysql_query("ALTER TABLE {$tab} DROP INDEX {$row[2]}");
            MysqlError();
            echo "Dropped index {$row[2]}. Unique: {$row[1]}\n";
        }
    }

    $res = mysql_query("DESCRIBE {$tab}");
    MysqlError();
    while (($row = mysql_fetch_array($res)) != null)
    {
        $name = $row[0];
        $type = $row[1];
        $set = false;
        if (preg_match("/^varchar\((\d+)\)$/i", $type, $mat))
        {
            $size = $mat[1];
            mysql_query("ALTER TABLE {$tab} MODIFY {$name} VARBINARY({$size})");
            MysqlError();
            mysql_query("ALTER TABLE {$tab} MODIFY {$name} VARCHAR({$size}) CHARACTER SET {$target_charset}");
            MysqlError();
            $set = true;

            echo "Altered field {$name} on {$tab} from type {$type}\n";
        }
        else if (!strcasecmp($type, "CHAR"))
        {
            mysql_query("ALTER TABLE {$tab} MODIFY {$name} BINARY(1)");
            MysqlError();
            mysql_query("ALTER TABLE {$tab} MODIFY {$name} VARCHAR(1) CHARACTER SET {$target_charset}");
            MysqlError();
            $set = true;

            echo "Altered field {$name} on {$tab} from type {$type}\n";
        }
        else if (!strcasecmp($type, "TINYTEXT"))
        {
            mysql_query("ALTER TABLE {$tab} MODIFY {$name} TINYBLOB");
            MysqlError();
            mysql_query("ALTER TABLE {$tab} MODIFY {$name} TINYTEXT CHARACTER SET {$target_charset}");
            MysqlError();
            $set = true;

            echo "Altered field {$name} on {$tab} from type {$type}\n";
        }
        else if (!strcasecmp($type, "MEDIUMTEXT"))
        {
            mysql_query("ALTER TABLE {$tab} MODIFY {$name} MEDIUMBLOB");
            MysqlError();
            mysql_query("ALTER TABLE {$tab} MODIFY {$name} MEDIUMTEXT CHARACTER SET {$target_charset}");
            MysqlError();
            $set = true;

            echo "Altered field {$name} on {$tab} from type {$type}\n";
        }
        else if (!strcasecmp($type, "LONGTEXT"))
        {
            mysql_query("ALTER TABLE {$tab} MODIFY {$name} LONGBLOB");
            MysqlError();
            mysql_query("ALTER TABLE {$tab} MODIFY {$name} LONGTEXT CHARACTER SET {$target_charset}");
            MysqlError();
            $set = true;

            echo "Altered field {$name} on {$tab} from type {$type}\n";
        }
        else if (!strcasecmp($type, "TEXT"))
        {
            mysql_query("ALTER TABLE {$tab} MODIFY {$name} BLOB");
            MysqlError();
            mysql_query("ALTER TABLE {$tab} MODIFY {$name} TEXT CHARACTER SET {$target_charset}");
            MysqlError();
            $set = true;

            echo "Altered field {$name} on {$tab} from type {$type}\n";
        }

        if ($set)
            mysql_query("ALTER TABLE {$tab} MODIFY {$name} COLLATE {$target_collate}");
    }

    // re-build indicies..
    foreach ($indicies as $index)
    {
        if ($index["unique"])
        {
            mysql_query("CREATE UNIQUE INDEX {$index["name"]} ON {$tab} ({$index["col"]})");
            MysqlError();
        }
        else
        {
            mysql_query("CREATE INDEX {$index["name"]} ON {$tab} ({$index["col"]})");
            MysqlError();
        }

        echo "Created index {$index["name"]} on {$tab}. Unique: {$index["unique"]}\n";
    }

    // set default collate
    mysql_query("ALTER TABLE {$tab}  DEFAULT CHARACTER SET {$target_charset} COLLATE {$target_collate}");
}

// set database charset
mysql_query("ALTER DATABASE {$db} DEFAULT CHARACTER SET {$target_charset} COLLATE {$target_collate}");

mysql_close($conn);
echo "</pre>";

?>
Run Code Online (Sandbox Code Playgroud)

  • 注意:通过查看源代码,在我看来,这个脚本不会重新创建多列唯一索引,它只是丢弃它们. (4认同)

Buz*_*uzz 23

小心!如果你实际上将utf存储为另一种编码,你的手上可能会有一个真正的混乱.先备份.然后尝试一些标准方法:

例如 http://www.cesspit.net/drupal/node/898 http://www.hackszine.com/blog/archive/2007/05/mysql_database_migration_latin.html

我不得不求助于将所有文本字段转换为二进制文件,然后再转换为varchar/text.这节省了我的屁股.

我的数据是UTF8,存储为latin1.我做了什么:

删除索引.将字段转换为二进制.转换为utf8-general ci

如果您在LAMP上,请不要忘记在与db交互之前添加set NAMES命令,并确保设置字符编码头.


Ric*_*ams 13

此PHP代码段将更改数据库中所有表的排序规则.(它来自这个网站.)

<?php
// your connection
mysql_connect("localhost","root","***");
mysql_select_db("db1");

// convert code
$res = mysql_query("SHOW TABLES");
while ($row = mysql_fetch_array($res))
{
    foreach ($row as $key => $table)
    {
        mysql_query("ALTER TABLE " . $table . " CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci");
        echo $key . " =&gt; " . $table . " CONVERTED<br />";
    }
}
?> 
Run Code Online (Sandbox Code Playgroud)