将所有表和字段更改为MYSQL中utf-8-bin排序规则的脚本
我可以运行一个" SQL"或者" PHP"脚本来更改数据库中所有表和字段的默认排序规则吗?
我可以自己写一个,但我认为这应该是在这样的站点上容易获得的东西。如果我可以在有人发布一个之前自己提出一个,我会自己发布。
解决方案
当心!如果我们实际上已将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-genci
如果我们使用的是LAMP,请不要忘记在与数据库进行交互之前添加set NAMES命令,并确保设置了字符编码标头。
这个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 . " => " . $table . " CONVERTED<br />"; } } ?>
字符集和排序规则不是一回事。排序规则是有关如何对字符串进行排序的一组规则。字符集是有关如何表示字符的一组规则。排序规则取决于字符集。
好的,我在撰写本文时已考虑到该线程中所说的内容。感谢帮助,我希望这个脚本能对其他人有所帮助。我对其使用没有任何保证,因此请在运行前进行备份。它应该与所有数据库一起使用;就我自己而言,效果很好。
编辑:在顶部将varset转换为charset / collate。
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>"; ?>
可以在一个命令中完成(而不是PHP的148个):
mysql --database=dbname -B -N -e "SHOW TABLES" \ | awk '{print "SET foreign_key_checks = 0; ALTER TABLE", , "CONVERT TO CHARACTER SET utf8 COLLATE utf8_general_ci; SET foreign_key_checks = 1; "}' \ | mysql --database=dbname &
我们一定喜欢命令行...
(我们可能需要为mysql使用--user
和--password
选项)。
编辑:为避免外键问题,添加了" SET foreign_key_checks = 0;"和" SET foreign_key_checks = 1;"。
我认为在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
第2步:
该查询将输出查询列表,每个表一个。我们必须复制查询列表,然后将其粘贴到命令行或者PhpMyAdmin的SQL选项卡中才能进行更改。