将包含混合入侵类型的SQL_ASCII的Postgresql数据库转换为UTF-8

时间:2010-11-02 16:42:04

标签: sql database postgresql encoding utf-8

我有一个postgresql数据库我想转换为UTF-8。

问题是它当前是SQL_ASCII,因此没有对其输入进行任何类型的编码转换,因此最终得到了表中混合编码类型的数据。一行可能包含编码为UTF-8的值,另一行可能包含ISO-8859-x或Windows-125x等。

这使得执行数据库转储,并将其转换为UTF-8,目的是将其导入新的UTF-8数据库,这很困难。如果数据都是一种编码类型,我可以通过iconv运行转储文件,但我认为这种方法不适用于此。

问题根本在于了解每个数据的编码方式吗?在这里,不知道的地方,可以解决,甚至猜测吗?理想情况下,我喜欢一个脚本,它可以获取文件,任何文件,并吐出有效的UTF-8。

4 个答案:

答案 0 :(得分:4)

完全 Encoding::FixLatin为解决*而编写的问题。

如果您安装了Perl模块,那么您还将获得fix_latin命令行实用程序,您可以像这样使用它:

pg_restore -O dump_file | fix_latin | psql -d database

阅读文档的“Limitations”部分,了解其工作原理。

[*]注意我假设当你说ISO-8859-x你的意思是ISO-8859-1,当你说CP125x你的意思是CP1252 - 因为混合了ASCII,UTF-8,Latin-1和WinLatin-1是一种常见情况。但是,如果你确实混合了东方和西方的编码,那么很抱歉,但是你被搞砸了: - (

答案 1 :(得分:1)

如果没有先了解数据,就不可能。你知道这是短信还是人的名字或地方?用某种语言?

您可以尝试对转储行进行编码并应用一些启发式算法 - 例如尝试使用自动拼写检查程序并选择生成最少错误数或最常用单词等的编码。

您可以使用例如aspell list -l enen表示英语,pl表示波兰语,fr表示法语等)以获取拼写错误的单词列表。然后,您可以选择生成最少的编码。您需要在我的Fedora 13 Linux系统中安装相应的字典包,例如“aspell-en”。

答案 2 :(得分:0)

实际上,我自己也看到了这个问题。简短的回答:没有简单的算法。但是有一些希望。

首先,根据我的经验,数据往往是:

  • 99%ASCII
  • .9%UTF-8
  • .1%其他,其中75%是Windows-1252。

所以让我们用它。您需要分析自己的数据集,以查看它是否遵循此模式。 (我在美国,所以这是典型的。我想,一个包含欧洲数据的数据库可能不会那么幸运,而东方的数据更是如此。)

首先,今天大多数编码都包含ASCII作为子集。 UTF-8,ISO-8859-1,等等。因此,如果一个字段只包含[0,0x7F]范围内的八位字节(即ASCII字符),那么它可能以ASCII / UTF-8 / ISO-编码8859-1 /等。如果你正在处理美国英语,这可能会照顾你99%的数据。

留下什么。

UTF-8有一些不错的属性,因为它将是1字节的ASCII字符,或者第一个字节后的所有内容都是二进制的10xxxxxx。所以:尝试通过一个UTF-8解码器来运行你剩下的字段(如果你给它垃圾就会窒息。)在它没有阻塞的字段上,我的经验是它们可能是有效的UTF-8。 (这里有可能产生误报:我们可能有一个棘手的ISO-8859-1字段也是有效的UTF-8。)

最后,如果它不是ASCII,并且它不能解码为UTF-8,Windows-1252似乎是下一个尝试的好选择。几乎所有东西都是有效的Windows-1252,所以这里很难搞到失败。

您可以这样做:

  • 尝试解码为ASCII。如果成功,则假设为ASCII。
  • 尝试解码为UTF-8。
  • 尝试解码为Windows-1252

对于UTF-8和Windows-1252,将表的PK和“guess”解码文本输出到文本文件(在输出之前将Windows-1252转换为UTF-8)。让人看一眼,看看他们是否看到任何不合适的地方。如果没有太多的非ASCII数据(就像我说的那样,如果你在美国,那么ASCII往往占主导地位......),那么一个人可以看看整个事物。

此外,如果您对数据的外观有所了解,可以将解码限制为某些字符。例如,如果一个字段解码为有效的UTF-8文本,但包含一个“©”,并且该字段是一个人的名字,那么它可能是误报,应该更仔细地查看。

最后,请注意,当您更改为UTF-8数据库时,过去插入此垃圾数据的任何内容可能仍然存在:您需要跟踪此系统并教它字符编码。

答案 3 :(得分:0)

我决定使用这个命令;

1-)导出

pg_dump --username=postgres --encoding=ISO88591 database -f database.sql

之后

2-)导入

psql -U postgres -d database < database.sql

这些命令帮助我解决了转换SQL_ASCII - UTF-8

的问题