如何将整个MySQL数据库字符集转换为UTF-8和排序为UTF-8?
当前回答
DELIMITER $$
CREATE PROCEDURE `databasename`.`update_char_set`()
BEGIN
DECLARE done INT DEFAULT 0;
DECLARE t_sql VARCHAR(256);
DECLARE tableName VARCHAR(128);
DECLARE lists CURSOR FOR SELECT table_name FROM `information_schema`.`TABLES` WHERE table_schema = 'databasename';
DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done = 1;
OPEN lists;
FETCH lists INTO tableName;
REPEAT
SET @t_sql = CONCAT('ALTER TABLE ', tableName, ' CONVERT TO CHARACTER SET utf8 COLLATE utf8_general_ci');
PREPARE stmt FROM @t_sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
FETCH lists INTO tableName;
UNTIL done END REPEAT;
CLOSE lists;
END$$
DELIMITER ;
CALL databasename.update_char_set();
其他回答
最安全的方法是先将列修改为二进制类型,然后使用所需的字符集将其修改回二进制类型。
每种列类型都有其各自的二进制类型,如下所示:
>二进制 文本=> BLOB 丁文字=> TINYBLOB 文本=> memblob LONGTEXT => LONGBLOB VARCHAR => VARBINARY
Eg.:
ALTER TABLE [TABLE_SCHEMA].[TABLE_NAME] MODIFY [COLUMN_NAME] VARBINARY;
ALTER TABLE [TABLE_SCHEMA].[TABLE_NAME] MODIFY [COLUMN_NAME] VARCHAR(140) CHARACTER SET utf8mb4;
我尝试了几个拉丁表,它保留了所有的变音符。
你可以为所有列提取这个查询:
SELECT
CONCAT('ALTER TABLE ', TABLE_SCHEMA,'.', TABLE_NAME,' MODIFY ', COLUMN_NAME,' VARBINARY;'),
CONCAT('ALTER TABLE ', TABLE_SCHEMA,'.', TABLE_NAME,' MODIFY ', COLUMN_NAME,' ', COLUMN_TYPE,' CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;')
FROM information_schema.columns
WHERE TABLE_SCHEMA IN ('[TABLE_SCHEMA]')
AND COLUMN_TYPE LIKE 'varchar%'
AND (COLLATION_NAME IS NOT NULL AND COLLATION_NAME NOT LIKE 'utf%');
在所有列上执行此操作后,再对所有表执行此操作:
ALTER TABLE [TABLE_SCHEMA].[TABLE_NAME] CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
要为你所有的表生成这个查询,使用下面的查询:
SELECT
CONCAT('ALTER TABLE ', TABLE_SCHEMA, '.', TABLE_NAME, ' CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;')
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_COLLATION NOT LIKE 'utf8%'
and TABLE_SCHEMA in ('[TABLE_SCHEMA]');
现在你修改了所有的列和表,在数据库上做同样的事情:
ALTER DATABASE [DATA_BASE_NAME] CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci;
使用HeidiSQL。它是免费的,而且是一个非常好的数据库工具。
从工具菜单,进入批量表编辑器
选择完整的数据库或选择表进行转换,
tick更改默认排序规则:utf8mb4_general_ci tick转换为字符集:utf8
执行
这将在短短几秒钟内将完整的数据库从拉丁语转换为utf8。
工作就像一个魅力:)
HeidiSQL默认连接为utf8,因此任何特殊字符现在都应该被视为字符(æ ø å),而不是在检查表数据时被编码。
从latin到utf8的真正陷阱是确保pdo与utf8字符集连接。如果不是,你会得到垃圾数据插入到utf8表和问号在你的网页上到处都是,让你认为表数据不是utf8…
mysqldump -uusername -ppassword -c -e --default-character-set=utf8 --single-transaction --skip-set-charset --add-drop-database -B dbname > dump.sql
cp dump.sql dump-fixed.sql
vim dump-fixed.sql
:%s/DEFAULT CHARACTER SET latin1/DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci/
:%s/DEFAULT CHARSET=latin1/DEFAULT CHARSET=utf8/
:wq
mysql -uusername -ppassword < dump-fixed.sql
如果数据不在相同的字符集中,您可以考虑http://dev.mysql.com/doc/refman/5.0/en/charset-conversion.html中的这个片段
如果列具有非二进制数据类型(CHAR、VARCHAR、TEXT),则其 内容应该在列字符集中编码,而不是其他字符集 字符集。如果内容用不同的字符编码 设置后,您可以先将列转换为使用二进制数据类型,然后 然后转换到具有所需字符集的非二进制列。
这里有一个例子:
ALTER TABLE t1 CHANGE c1 c1 BLOB;
ALTER TABLE t1 CHANGE c1 c1 VARCHAR(100) CHARACTER SET utf8;
确保选择正确的排序规则,否则可能会得到唯一的键冲突。如。 Éleanore和Eleanore在某些排序中可能被认为是相同的。
旁白:
我曾遇到过这样的情况,电子邮件中的某些字符“坏了”,尽管它们在数据库中以UTF-8格式存储。如果您使用utf8数据发送电子邮件,您可能还需要将电子邮件转换为utf8发送。
在phpailer中,只需更新这一行:public $CharSet = 'utf-8';
如果你不能让你的表转换,或者你的表总是设置为一些非utf8字符集,但你想要utf8,你最好的办法可能是擦掉它,重新开始,并显式地指定:
create database database_name character set utf8;