如何将整个MySQL数据库characterset和collat​​ion转换为UTF-8?

Dea*_*ean 442 mysql character-encoding

如何将整个MySQL数据库字符集转换为UTF-8并将整理转换为UTF-8?

Bal*_*usC 685

使用ALTER DATABASEALTER TABLE命令.

ALTER DATABASE databasename CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
ALTER TABLE tablename CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
Run Code Online (Sandbox Code Playgroud)

或者,如果您仍然使用不支持4字节UTF-8的MySQL 5.5.2或更早版本,请使用utf8而不是utf8mb4:

ALTER DATABASE databasename CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE tablename CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;
Run Code Online (Sandbox Code Playgroud)

  • `CONVERT TO`技术假定文本_correctly_存储在其他一些字符集(例如,latin1)中,而不是被修改(例如UTF-8字节塞入latin1列而不转换为latin1). (10认同)
  • 将字符集更改为 utf8 会将我的数据类型从文本更改为中型文本。是预期的吗? (3认同)
  • 这会重建表,使其在大型生产系统上不可行。如果确定只有 ASCII 字符存储在 latin1 列中,是否可以在不重建的情况下更改表字符集/排序规则? (2认同)
  • @Jerry可能是因为:“如果列转换为utf8,每个字符可能需要最多三个字节,最大可能长度为3×65,535 = 196,605字节。该长度不适合TEXT列的长度字节,所以MySQL 将数据类型转换为 MEDIUMTEXT,这是长度字节可以记录值 196,605 的最小字符串类型。类似地,VARCHAR 列可能会转换为 MEDIUMTEXT。” [更改字符集](https://dev.mysql.com/doc/refman/8.0/en/alter-table.html#alter-table-character-set) (2认同)

new*_*ire 124

  1. 做个备份!

  2. 然后,您需要在数据库上设置默认字符集.这不会转换现有表,它只为新创建的表设置默认值.

    ALTER DATABASE dbname CHARACTER SET utf8 COLLATE utf8_general_ci;
    
    Run Code Online (Sandbox Code Playgroud)
  3. 然后,您将需要转换所有现有表及其列的char集.这假设您当前的数据实际上在当前的char集中.如果您的列设置为一个字符集但您的数据确实存储在另一个字符集中,则需要检查MySQL手册以了解如何处理此问题.

    ALTER TABLE tbl_name CONVERT TO CHARACTER SET utf8 COLLATE utf8_general_ci;
    
    Run Code Online (Sandbox Code Playgroud)

  • 注意:ALTER TABLE tablename CHARACTER SET utf8仅设置用于新创建的列的表的默认字符集.它不会转换已设置char集的现有列. (44认同)
  • 请注意,不再推荐使用`utf8_general_ci`作为最佳实践.从MySQL 5.5.3开始,你应该使用`utf8mb4`而不是`utf8`.它们都引用了UTF-8编码,但较旧的`utf8`具有MySQL特定的限制,阻止使用编号高于`0xFFFD`的字符. (15认同)
  • @DominikAngerer:什么破了? (4认同)

Jas*_*els 72

在命令行shell上

如果您是命令行shell,那么您可以非常快速地执行此操作.只需填写"dbname":D

DB="dbname"
(
    echo 'ALTER DATABASE `'"$DB"'` CHARACTER SET utf8 COLLATE utf8_general_ci;'
    mysql "$DB" -e "SHOW TABLES" --batch --skip-column-names \
    | xargs -I{} echo 'ALTER TABLE `'{}'` CONVERT TO CHARACTER SET utf8 COLLATE utf8_general_ci;'
) \
| mysql "$DB"
Run Code Online (Sandbox Code Playgroud)

One-liner用于简单复制/粘贴

DB="dbname"; ( echo 'ALTER DATABASE `'"$DB"'` CHARACTER SET utf8 COLLATE utf8_general_ci;'; mysql "$DB" -e "SHOW TABLES" --batch --skip-column-names | xargs -I{} echo 'ALTER TABLE `'{}'` CONVERT TO CHARACTER SET utf8 COLLATE utf8_general_ci;' ) | mysql "$DB"
Run Code Online (Sandbox Code Playgroud)

  • 这段代码效果很好,只需记住在mysql之后添加-h [hostname] -u [username] -p [password]. (6认同)
  • 您可能希望在实际系统上禁用外键检查:`DB ="db_name"; (echo'ALTER DATABASE`'"$ DB"'`CHARACTER SET utf8 COLLATE utf8_general_ci;'; mysql --uuser -ppassword -hhost"$ DB"-e"SHOW TABLES"--batch --skip-column-names | xargs -I {} echo'SET foreign_key_checks = 0; ALTER TABLE`' {}'`CONVERT TO CHARACTER SET utf8 COLLATE utf8_general_ci;')| mysql -uuser -ppassword -hhost"$ DB"` (3认同)
  • 你可以在这里加入更多的细节我得到`ERROR 1064(42000):你的SQL语法有错误; 检查与MySQL服务器版本对应的手册,以便在'DB ="dbname"`附近使用正确的语法 (2认同)

sdf*_*for 69

您可以使用以下命令创建sql以更新所有表:

SELECT CONCAT("ALTER TABLE ",TABLE_SCHEMA,".",TABLE_NAME," CHARACTER SET utf8 COLLATE utf8_general_ci;   ",
    "ALTER TABLE ",TABLE_SCHEMA,".",TABLE_NAME," CONVERT TO CHARACTER SET utf8 COLLATE utf8_general_ci;  ") 
    AS alter_sql
FROM information_schema.TABLES
WHERE TABLE_SCHEMA = your_database_name;
Run Code Online (Sandbox Code Playgroud)

捕获输出并运行它.

Arnold Daniels上面的回答更优雅.

  • @Akshay,好问题.第一个alter-table查询设置新列的默认值,第二个alter-table查询转换现有列. (7认同)
  • 仅供参考:根据http://dev.mysql.com/doc/refman/5.5/en/alter-table.html MySQL文档,ALTER语句的"CONVERT TO CHARACTER SET"版本只需一步完成:"To将表默认字符集**和**所有字符列(CHAR,VARCHAR,TEXT)更改为新的字符集... (4认同)
  • 我收到此错误#1054-'where子句'中的未知列'webdb_playground',但是我确定我的数据库是正确的 (2认同)

Joh*_*Yin 17

在继续之前,请确保您:已完成完整的数据库备份!

第1步:数据库级别更改

  • 识别数据库的排序规则和字符集

    SELECT DEFAULT_CHARACTER_SET_NAME, DEFAULT_COLLATION_NAME FROM 
    information_schema.SCHEMATA S
    WHERE schema_name = 'your_database_name'
    AND
    (DEFAULT_CHARACTER_SET_NAME != 'utf8'
        OR
     DEFAULT_COLLATION_NAME not like 'utf8%');
    
    Run Code Online (Sandbox Code Playgroud)
  • 修复数据库的排序规则

    ALTER DATABASE databasename CHARACTER SET utf8 COLLATE utf8_unicode_ci;
    
    Run Code Online (Sandbox Code Playgroud)

第2步:表级更改

  • 使用不正确的字符集或排序规则识别数据库表

    SELECT CONCAT(
    'ALTER TABLE ',  table_name, ' CHARACTER SET utf8 COLLATE utf8_general_ci;  ', 
    'ALTER TABLE ',  table_name, ' CONVERT TO CHARACTER SET utf8 COLLATE utf8_general_ci;  ')
    FROM information_schema.TABLES AS T, information_schema.`COLLATION_CHARACTER_SET_APPLICABILITY` AS C
    WHERE C.collation_name = T.table_collation
    AND T.table_schema = 'your_database_name'
    AND
    (C.CHARACTER_SET_NAME != 'utf8'
        OR
     C.COLLATION_NAME not like 'utf8%')
    
    Run Code Online (Sandbox Code Playgroud)
  • 调整表列的排序规则和字符集

捕获上层sql输出并运行它.(如下)

ALTER TABLE rma CHARACTER SET utf8 COLLATE utf8_general_ci;ALTER TABLE rma CONVERT TO CHARACTER SET utf8 COLLATE utf8_general_ci;  
ALTER TABLE rma_history CHARACTER SET utf8 COLLATE utf8_general_ci;ALTER TABLE rma_history CONVERT TO CHARACTER SET utf8 COLLATE utf8_general_ci;  
ALTER TABLE rma_products CHARACTER SET utf8 COLLATE utf8_general_ci;ALTER TABLE rma_products CONVERT TO CHARACTER SET utf8 COLLATE utf8_general_ci;  
ALTER TABLE rma_report_period CHARACTER SET utf8 COLLATE utf8_general_ci;ALTER TABLE rma_report_period CONVERT TO CHARACTER SET utf8 COLLATE utf8_general_ci;  
ALTER TABLE rma_reservation CHARACTER SET utf8 COLLATE utf8_general_ci;ALTER TABLE rma_reservation CONVERT TO CHARACTER SET utf8 COLLATE utf8_general_ci;  
ALTER TABLE rma_supplier_return CHARACTER SET utf8 COLLATE utf8_general_ci;ALTER TABLE rma_supplier_return CONVERT TO CHARACTER SET utf8 COLLATE utf8_general_ci;  
ALTER TABLE rma_supplier_return_history CHARACTER SET utf8 COLLATE utf8_general_ci;ALTER TABLE rma_supplier_return_history CONVERT TO CHARACTER SET utf8 COLLATE utf8_general_ci;  
ALTER TABLE rma_supplier_return_product CHARACTER SET utf8 COLLATE utf8_general_ci;ALTER TABLE rma_supplier_return_product CONVERT TO CHARACTER SET utf8 COLLATE utf8_general_ci; 
Run Code Online (Sandbox Code Playgroud)

参考:https://confluence.atlassian.com/display/CONFKB/How+to+Fix+the+Collat​​ion+and+Character+Set+of+a+MySQL+Database


小智 7

使用HeidiSQL.它是免费的,非常好的数据库工具.

从工具菜单中,输入批量表编辑器

选择完整的数据库或选择要转换的表,

  • tick更改默认排序规则:utf8mb4_general_ci
  • tick转换为charset:utf8

执行

这将在几秒钟内将完整的数据库从拉丁语转换为utf8.

奇迹般有效 :)

HeidiSQL默认连接为utf8,因此任何特殊字符现在应该被视为字符(æøå),而不是在检查表数据时编码.

从拉丁语转到utf8时真正的陷阱是确保pdo与utf8 charset连接.如果没有,你会将垃圾数据插入到utf8表格并在网页上的所有地方出现问号,让你认为表格数据不是utf8 ...


小智 6

受@sdfor评论的启发,这是一个完成这项工作的bash脚本

#!/bin/bash

printf "### Converting MySQL character set ###\n\n"

printf "Enter the encoding you want to set: "
read -r CHARSET

# Get the MySQL username
printf "Enter mysql username: "
read -r USERNAME

# Get the MySQL password
printf "Enter mysql password for user %s:" "$USERNAME"
read -rs PASSWORD

DBLIST=( mydatabase1 mydatabase2 )

printf "\n"


for DB in "${DBLIST[@]}"
do
(
    echo 'ALTER DATABASE `'"$DB"'` CHARACTER SET utf8 COLLATE `'"$CHARSET"'`;'
    mysql "$DB" -u"$USERNAME" -p"$PASSWORD" -e "SHOW TABLES" --batch --skip-column-names \
    | xargs -I{} echo 'ALTER TABLE `'{}'` CONVERT TO CHARACTER SET utf8 COLLATE `'"$CHARSET"'`;'
) \
| mysql "$DB" -u"$USERNAME" -p"$PASSWORD"

echo "$DB database done..."
done

echo "### DONE ###"
exit
Run Code Online (Sandbox Code Playgroud)


小智 5

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();
Run Code Online (Sandbox Code Playgroud)