2011-05-06 131 views
124

我们以前的程序员在表中设置了错误的排序规则(Mysql)。他用拉丁语整理,当它应该是UTF8,现在我有问题。每个有中国和日本字符的记录转到???字符。如何更改数据库的默认排序规则?

是否可以更改排序规则并取回字符的细节?

+0

可能重复[MySql alter table Collat​​ion](http://stackoverflow.com/questions/742205/mysql-alter-table-collat​​ion) – kenorb 2015-03-03 14:45:44

回答

285

改变数据库排序规则:

ALTER DATABASE <database_name> CHARACTER SET utf8 COLLATE utf8_unicode_ci; 

变化表归类:

ALTER TABLE <table_name> CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci; 

变化列排序规则:

ALTER TABLE <table_name> MODIFY <column_name> VARCHAR(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci; 

更多信息:

+4

请注意'CHARACTER SET utf8'将默认为'utf8_general_ci',但您也可以定义这样的排序规则:'ALTER DATABASE CHARACTER SET utf8 COLLATE utf8_unicode_ci;'如果需要 – KCD 2014-02-17 08:10:41

+0

...并且我建议你测试它'create table testit(a varchar(1));显示创建表testit \ G drop table testit;' – KCD 2014-02-17 08:13:07

+0

谢谢@Timo Huovinen,命令工作像魅力:D – 2014-06-03 17:40:35

3

here很好地描述了这个过程。但是,一些不适合拉丁空间的角色将永远消失。 UTF-8是latin1的SUPERSET。不是相反的。大多数人会适合单字节的空间,但任何不确定的人不会(检查LATIN1名单 - 不是所有的256个字符的定义,取决于MySQL的latin1的定义)

14

要注意的是在MySQL中,utf8字符集是只有真正的UTF8字符集的一个子集。为了节省一个字节的存储空间,Mysql团队决定只存储三个字节的UTF8字符而不是四个字节。这意味着一些东亚语言和表情符号不完全支持。为确保可以存储所有UTF8字符,请在Mysql中使用utf8mb4数据类型,并使用utf8mb4_binutf8mb4_general_ci

+1

这是非常有帮助:) – Raz0rwire 2016-07-14 05:02:23

+1

也阅读http://stackoverflow.com/questions/367711/what-is-the-best-collat​​ion-to-use-for-mysql-with-php?rq=1 – 2016-09-08 07:40:21

29

如何更改所有数据库/表/列。运行这些查询,它们将输出将整个模式转换为utf8所需的所有后续查询。希望这可以帮助!

- 更改数据库的默认排序规则

SELECT DISTINCT concat('ALTER DATABASE `', TABLE_SCHEMA, '` CHARACTER SET utf8 COLLATE utf8_unicode_ci;') 
from information_schema.tables 
where TABLE_SCHEMA like 'database_name'; 

- 更改表整理/字符集

SELECT concat('ALTER TABLE `', TABLE_SCHEMA, '`.`', table_name, '` CHARACTER SET utf8 COLLATE utf8_unicode_ci;') 
from information_schema.tables 
where TABLE_SCHEMA like 'database_name'; 

- 更改列排序规则/字符集

SELECT concat('ALTER TABLE `', t1.TABLE_SCHEMA, '`.`', t1.table_name, '` MODIFY `', t1.column_name, '` ', t1.data_type , '(' , t1.CHARACTER_MAXIMUM_LENGTH , ')' , ' CHARACTER SET utf8 COLLATE utf8_unicode_ci;') 
from information_schema.columns t1 
where t1.TABLE_SCHEMA like 'database_name' and t1.COLLATION_NAME = 'old_charset_name'; 
+0

好。 !大约一个小时,我试图解决同样的问题。我使用这3个命令,并且我看到字符集已经改变了。但主要问题仍然存在。如果我直接写入数据库,那么在我的浏览器中一切都很好。但是,如果我从网站表单添加了一些内容,数据库中的结果就是??????。有什么我应该考虑的吗?我的网络应用程序是一个.NET MVC应用程序。 – Tchaps 2015-07-11 16:16:47

+0

保存到未来项目的有用查询中。 – Manatax 2016-03-01 23:08:44

+0

我提出了一些编辑,因为这些自动查询还不够安全。 CHARACTER_MAXIMUM_LENGTH仍然存在问题:当您从例如“最新动态”更改为“最新动态”时,该值可能会过高。 latin1_swedish_ci到utf8_unicode_ci。 – Ruben 2016-05-03 15:06:37

4

添加到什么大卫Whittaker发布,我创建了一个查询生成完整的表和列alter语句w虐待每个表转换。运行

SET SESSION group_concat_max_len = 100000;

首先要确保您的组concat不超过极限,如here所示。

 SELECT a.table_name, concat('ALTER TABLE ', a.table_schema, '.', a.table_name, ' DEFAULT CHARACTER SET utf8mb4 DEFAULT COLLATE utf8mb4_unicode_ci, ', 
     group_concat(distinct(concat(' MODIFY ', column_name, ' ', column_type, ' CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci ', if (is_nullable = 'NO', ' NOT', ''), ' NULL ', 
     if (COLUMN_DEFAULT is not null, CONCAT(' DEFAULT \'', COLUMN_DEFAULT, '\''), ''), if (EXTRA != '', CONCAT(' ', EXTRA), '')))), ';') as alter_statement 
    FROM information_schema.columns a 
    INNER JOIN INFORMATION_SCHEMA.TABLES b ON a.TABLE_CATALOG = b.TABLE_CATALOG 
     AND a.TABLE_SCHEMA = b.TABLE_SCHEMA 
     AND a.TABLE_NAME = b.TABLE_NAME 
     AND b.table_type != 'view' 
    WHERE a.table_schema = ? and (collation_name = 'latin1_swedish_ci' or collation_name = 'utf8mb4_general_ci') 
    GROUP BY table_name; 

以前的答案之间这里的差别在于它使用UTF-8,而不是ut8mb4并使用与t1.CHARACTER_MAXIMUM_LENGTH t1.data_type对枚举没有工作了。此外,我的查询排除视图,因为这些视图将分别进行更改。

我简单地使用Perl脚本将所有这些变量作为数组返回并遍历它们,修复了太长的列(当数据通常只有20个字符时,通常它们是varchar(256)是一个简单的修复)。

我发现一些数据在从latin1 - > utf8mb4改变时被破坏。它似乎是UTF8编码的拉丁字符在列中会被转化为伪装。我只是从列前面和后面的列中知道将要成为内存问题的列中的数据,并将它们进行比较并生成更新语句以修复数据。

相关问题