1

在我的公司,数据库中的表创建得很差。每个表都有不同的排序规则和字符集。

当然,这非常糟糕,但它会使查询失去很多性能,直到服务器崩溃(它甚至不是一个很好的数据库......)。

我想知道是否有任何好的 MySQL 工具、命令或程序来转换表排序规则和字符集。

仅仅执行alter table 并执行convert 就是制动特殊字符。这是正常的还是我做错了什么?

编辑: 例如:我有一个带有 uft8 整理的表格财务和一个带有拉丁瑞典语的表格费用。每个表有 1000 到 5000 行。以下查询大约需要 15 秒才能执行:

select ex.* from expense ex
   inner join finance fin on fin.ex_id = ex.id

当它们具有相同的排序规则时,使用更大的表执行更复杂的查询会运行得更快。

编辑2: 数据库中的另一个错误:行ID都是varchar(15),而不是int。

4

3 回答 3

2

我知道继承那些认为“整理”是某种疾病的人创建的遗留模式的乐趣。

最好的选择是使用良好的 ole' mysqldump 将表及其数据导出到 SQL 转储文件。然后手动修改转储文件中的create语句来设置字符集和排序规则。我是“utf8”的忠实粉丝。如果转储文件很大,请使用命令行工具sed来有效地编辑文件,而无需在编辑器中打开它。

然后删除现有表重新导入修改后的转储。

根据我的经验,您这样做的任何其他方式都可能是掷骰子。

这可能是将它们全部转换为相同的存储引擎或将您的 MySQL 服务器升级到 5.5 的好时机。

于 2012-11-30T17:59:46.587 回答
1

我不建议使用“工具”来解决这个问题。

在您做任何事情之前转储您的数据库以进行备份,以防万一您搞砸了;)

您可以通过两种方式简化字符集和排序规则

方法 1:移动数据

  • 创建一个全新的数据库,在所有表中配置正确的字符集和排序规则

  • 用 INSERT SELECT 语句填充新表,例如

    插入到newdatabase. table选择 * 从olddatabasetable

MySQL 会自动将您的数据转换为正确的字符集

方法2:改变你的表

如果更改现有表的字符集,所有现有内容也将被转换

例如

旧桌子

CREATE TABLE `myWrongCharsetTable` (
  `name` varchar(255) COLLATE latin1_german1_ci NOT NULL DEFAULT ''
) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_german1_ci;

放一些数据做demo

INSERT INTO `myWrongCharsetTable` (`name`) VALUES ( 'I am a latino string' );
INSERT INTO `myWrongCharsetTable` (`name`) VALUES ( 'Mein Name ist Müller' );
INSERT INTO `myWrongCharsetTable` (`name`) VALUES ( 'Mein Name ist Möller' );

SELECT * FROM myWrongCharsetTable INTO outfile '/tmp/mylatinotable.csv';

在 UTF-8 控制台上,我这样做

# cat /tmp/mylatinotable.csv
I am a latino string
Mein Name ist M▒ller
Mein Name ist M▒ller

对,奇怪的字符集..这是在 utf-8 控制台上显示的 latin 1

# cat /tmp/mylatinotable.csv | iconv -f latin1 -t utf-8
I am a latino string
Mein Name ist Müller
Mein Name ist Möller

是的,一切都好

那么我现在该如何解决这个问题?

ALTER TABLE myWrongCharsetTable
    MODIFY name varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL DEFAULT '', 
    DEFAULT CHARSET = utf8 COLLATE utf8_unicode_ci;

就是这样 :)

再次写入outfile

mysql> SELECT * FROM myWrongCharsetTable INTO outfile '/tmp/latinoutf8.csv';
Query OK, 3 rows affected (0.01 sec)

mysql> exit
Bye
dbmaster-001 ~ # cat /tmp/latinoutf8.csv

I am a latino string
Mein Name ist Müller
Mein Name ist Möller

工作,一切都很好,我们很高兴

编辑:

其实还有一种方法

方法 3:转储、修改和重新加载数据

如果您擅长 sed 和 awk,您可以自动执行此操作,或手动编辑文件

# dump the structure, possibly routines and triggers
mysqldump -h yourhost -p -u youruser --no-data --triggers --skip-comments --routines yourdatabase > database_structure_routines.sql

# dump the data
mysqldump -h yourhost -p -u youruser --no-create-info --skip-triggers --skip-routines yourdatabase > database_data.sql

现在database_structure_routines.sql在您选择的编辑器中打开并根据需要修改表格

我建议在您的转储文件中删除所有评论,例如 /*!40101 SET character_set_client = utf8 */ 因为这可能会覆盖表默认值

完成后,创建一个新的数据库和结构

mysql > CREATE DATABASE `newDatabase` DEFAULT CHARSET utf8 COLLATE utf8_unicode_ci;
mysql > use `newDatabase`
mysql > ./database_structure_routines.sql;

不要忘记重新检查您的表格

mysql > SHOW CREATE TABLE `table`;

如果没关系,您可以重新导入数据,字符集转换将自动完成

mysql -h yourhost -p -u youruser newDatabase < database_data.sql

希望这可以帮助

于 2012-11-30T18:13:02.513 回答
0

您可以尝试使用 CONVERT 或 CAST 来更改字符集 - 创建一个新列并使用 CAST 用新的更正字符集填充新列。
http://dev.mysql.com/doc/refman/5.0/en/charset-convert.html

于 2012-11-30T17:59:16.930 回答