首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何在整个数据库中更改字符集(和排序规则)?

如何在整个数据库中更改字符集(和排序规则)?
EN

Stack Overflow用户
提问于 2011-05-06 11:53:01
回答 4查看 177.8K关注 0票数 194

我们之前的程序员在表(Mysql)中设置了错误的排序规则。他用拉丁文校对来设置它,当它应该是UTF8的时候,现在我有问题了。每一张带有中文和日文字符的记录都会变成?性格。

是否可以更改排序规则并恢复字符的详细信息?

EN

回答 4

Stack Overflow用户

发布于 2015-05-14 03:39:38

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

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

代码语言:javascript
复制
SELECT DISTINCT concat('ALTER DATABASE `', TABLE_SCHEMA, '` CHARACTER SET utf8 COLLATE utf8_unicode_ci;')
from information_schema.tables
where TABLE_SCHEMA like  'database_name';

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

代码语言:javascript
复制
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';

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

代码语言:javascript
复制
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';
票数 56
EN

Stack Overflow用户

发布于 2015-03-03 23:04:28

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

票数 28
EN

Stack Overflow用户

发布于 2016-09-17 06:22:01

除了David Whittaker发布的内容之外,我还创建了一个查询,该查询生成完整的表和列的alter语句,这些语句将转换每个表。运行以下命令可能是个好主意

设置会话group_concat_max_len = 100000;

首先,要确保您的组concat不会超过here所示的非常小的限制。

代码语言:javascript
复制
     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;

前一个答案的不同之处在于它使用了utf8而不是ut8mb4,并且将t1.data_type与t1.CHARACTER_MAXIMUM_LENGTH结合使用不适用于枚举。此外,我的查询不包括视图,因为这些视图必须单独更改。

我简单地使用Perl脚本将所有这些更改作为一个数组返回,并迭代它们,修复了太长的列(通常它们是varchar(256),而数据通常只有20个字符,所以这是一个简单的修复方法)。

从latin1 -> utf8mb4更改时,我发现一些数据已损坏。列中的latin1字符似乎是utf8编码的,在转换过程中可能会出错。我只是将alter之前和之后的列中的数据保存在内存中,并对它们进行比较,然后生成update语句来修复数据。

票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5906585

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档