我有一个postgresql数据库,我想转换为UTF-8。
问题是它当前是SQL_ASCII,所以没有对它的输入进行任何类型的编码转换,因此最终在表中得到了混合编码类型的数据。一行可能包含编码为UTF-8的值,另一行可能包含ISO-8859-x或Windows-125x等。
这使得执行数据库转储并将其转换为UTF-8并打算将其导入到新的UTF-8数据库变得困难。如果数据都是一种编码类型,我可以通过iconv运行转储文件,但我不认为这种方法在这里有效。
问题是否从根本上归结为知道每个数据是如何编码的?在这里,这是未知的,它能被计算出来,甚至猜测吗?理想情况下,我会喜欢一个脚本,它将接受一个文件,任何文件,并吐出有效的UTF-8。
发布于 2010-11-10 11:55:00
这就是 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、拉丁语-1和Win拉丁语-1的混合是一种常见的情况。但是如果你真的有东方和西方的混合编码,那么很抱歉,你搞砸了:-(
发布于 2010-11-03 00:58:37
如果不先了解一些数据,这是不可能的。你知道这是一条短信,还是人名或地名?用某种特定的语言?
您可以尝试对转储的一行进行编码,并应用一些启发式方法-例如,尝试使用自动拼写检查器,并选择一种生成最少错误或最常见单词的编码,等等。
例如,您可以使用aspell list -l en (en表示英语,pl表示波兰语,fr表示法语等)以获取拼写错误的单词列表。然后,您可以选择生成它们中最少的编码。您需要安装相应的字典包,例如,在我的Fedora13Linux系统中安装"aspell-en“。
发布于 2010-11-03 04:15:21
实际上,我自己也见过这个问题。简短的回答是:没有简单的算法。但还是有一些希望的。
首先,根据我的经验,数据往往是:
所以让我们使用它。您将需要分析您自己的数据集,以查看它是否遵循此模式。(我在美国,所以这是典型的。我想,一个包含基于欧洲的数据的数据库可能就没有那么幸运了,而更远的东方可能就没有那么幸运了。)
首先,现在几乎所有的编码都包含ASCII作为一个子集。因此,如果一个字段只包含0, 0x7F范围内的八位字节,那么它可能是以ASCII/ UTF-8 / ISO-8859-1 /etc编码的。
接下来是剩下的。
UTF-8有一些很好的属性,因为它要么是1字节的ASCII字符,要么是第一个字节之后的所有东西都是二进制的10xxxxxx。因此:尝试通过UTF-8解码器运行剩余的字段(如果您给它垃圾,这个解码器将会卡住)。在它不会阻塞的领域,我的经验是它们可能是有效的UTF-8。(这里可能会出现误报:我们可能有一个棘手的ISO-8859-1字段,它也是有效的UTF-8。)
最后,如果它不是ASCII,并且不能解码为UTF-8,那么Windows-1252似乎是下一个值得尝试的好选择。但是,几乎所有的东西都是有效的Windows-1252,所以在这里很难出现故障。
您可以这样做:
对于UTF-8和Windows-1252,将表的PK和“猜测”解码文本输出到文本文件(在输出之前将Windows-1252转换为UTF-8 )。让人看一下,看看他们有没有发现什么不对劲的地方。如果没有太多的非ASCII数据(就像我说的,ASCII倾向于占主导地位,如果你在美国……),那么人类可以查看整个过程。
此外,如果您对数据的外观有一些了解,则可以将解码限制为某些字符。例如,如果一个字段解码为有效的UTF-8文本,但包含一个"©",并且该字段是一个人名,那么它可能是一个假阳性,应该更仔细地检查。
最后,请注意,当您更改为UTF-8数据库时,过去插入此垃圾数据的任何内容可能仍然存在:您将需要跟踪此系统并教它字符编码。
https://stackoverflow.com/questions/4079956
复制相似问题