我很难确定一个问题,这个问题似乎与Postgres数据库中存在的奇怪字符有关.我正在使用Java从postgres中提取数据并将其加载到BigQuery中.偶尔我会注意到,有些价值观似乎在这个过程中无缘无故地发生了变化.仔细判断后,我发现在所有情况下,这个问题似乎都是由我认为不正常的角色引起的.
Postgres数据库编码为UTF-8.Java编码也是UTF-8.
下面是我所看到的一个例子:
我有一个文本字段,其中包含以下值:SÅ‚awomir
.
If I run this SQL:
select length('SÅ‚awomir')
我得到的值是9,看起来是正确的.但是,如果我将该字符串导出到文本文件中并在十六进制编辑器(在我的例子中使用十六进制编辑器扩展名为Visual Studio代码)中查看它,则该字符串的长度看起来是11,而不是9.仔细判断后,第二个和第三个字符由两个十六进制值表示,而不是像其他字符那样只有一个十六进制值.这些第二个和第三个字符由以下4个十六进制值表示:
C3 85 C2 82
个
Here's a screenshot of the HEX editor showing those characters. As you can see, the string seems to have 11 characters, not 9:
请帮我理解这些角色是什么,我能做些什么.它们是有效的UTF-8字符吗?如果是这样,为什么它们应该被Java程序转换,我如何才能阻止这种情况发生?
更新2023-10-31:感谢您@Laurenz Albe的回复.它很好地解释了所发生的事情(以及future 如何防止它),但我不确定它是否完全解决了我的问题,因为我没有能力控制将数据插入数据库的upstream 过程.
我还有几个相关的细节:
我们使用Google数据流从Postgres中提取数据并将其移动到BigQuery.当数据到达BigQuery时,它看起来与Postgres中的完全一样(这正是我想要的).当我使用Java(JDBC)从BigQuery中取出该值,然后将其插入到另一个BigQuery表中时,问题实际上就发生了.
我不是像"INSERT INTO...SELECT FROM.."这样的单一INSERT语句.在这种情况下,数据永远不会离开BigQuery.我所做的是首先获取数据,并将结果赋给一个Java变量.然后,在第二步中,我将该值插入到另一个BigQuery表中.当我这样做时,目标表中的数据会发生轻微的更改,所以我正在try 找出如何防止这种情况发生.
以下是原始值和移动到另一个表后的值的示例:
下面是我HEX查看器中相同文件的屏幕截图:
正如您所看到的,该值已发生了一些更改-新值似乎为c3 85 e2 80 9a
因此,我真正的问题是,我如何才能保留原始价值?在将数据放入Java然后再放回BigQuery的过程中似乎发生了一些事情.我的Java环境配置为使用UTF8编码,因此我对如何保留原始值感到有点困惑.