MySQL整理问题

时间:2012-11-30 17:16:34

标签: mysql database character-encoding

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

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

我想知道是否有任何好的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。

3 个答案:

答案 0 :(得分:2)

我知道继承遗留模式的乐趣,他们认为“整理”是某种形式的疾病。

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

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

根据我的经验,你做任何其他方式都可以成为骰子。

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

答案 1 :(得分:1)

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

在您做任何事情之前,如果您的数据库需要备份,请务必注意;)

您可以通过两种方式简化字符集和整理

方法1:移动数据

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

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

    INSERT INTO newdatabasetable SELECT * FROM olddatabasetable

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

方法2:更改表格

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

e.g。

旧表

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

将一些数据放入演示

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

对,奇怪的charset ..这是在utf-8控制台上显示的拉丁语

# 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

希望这有帮助

答案 2 :(得分:0)

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