哪个字符最适合用作 ETL 的分隔符?

Posted

技术标签:

【中文标题】哪个字符最适合用作 ETL 的分隔符?【英文标题】:Which is the best character to use as a delimiter for ETL? 【发布时间】:2013-08-12 17:21:08 【问题描述】:

我最近从 Informix 数据库中卸载了一个客户表,并且有几行被拒绝,因为客户名称列包含非转义的竖线(管道符号)字符,这是源数据库中的默认 DBDELIMITER。我发现他们的客户表单中的字段有一个输入掩码,允许输入任何字母数字字符,可以包括任何字母、数字或符号。所以我说服用户对该列进行全面更新,将管道符号更改为分号。我还发现了在不同列中包含星号和逗号的其他行。我可以想象如果这张表以 csv 格式卸载会发生什么,或者星号会造成什么损害!

定义为分隔符的最佳字符是什么? 如果表格已经被管道、逗号、星号、制表符、反斜杠等污染,那么清理它们的最佳方法是什么?

【问题讨论】:

【参考方案1】:

在我的工作中,我必须处理大量的叙述性数据。这总是一场噩梦,因为用户倾向于在其中放置任何字符,包括不可打印的字符。您可以运行清理操作,但每次加载数据时都必须这样做,而且它可能不会永远有效。最终有人会将您选择的每个字符作为分隔符放入,如果您的 CSV 处理库可以正确处理转义,这不是问题,但很多人不能。如果这是一次性加载/卸载,您可能没问题,但如果您必须更频繁地执行此操作....

在过去,我将分隔符更改为反引号“`”、波浪号“~”或插入符号“^”。目前的努力都失败了。我能想出的最佳解决方案是根本不使用 CSV 格式。我切换到 XML。即便如此,仍然存在 XML 非法字符,但可以使用 atlassian-xml-cleaner-0.1.jar 翻译出来。

【讨论】:

我想限制输入字母、数字和一些符号,而不是管道、逗号、反斜杠、星号、单引号和双引号,因为这些可能会导致即时和未来的问题。那么我是否应该编写一个例程来防止用户输入禁止的字符,并编写另一个例程来扫描 char 和 text 列以将它们转换为其他内容? 这里涉及到许多变量。首先,您的用户是数据输入的唯一来源吗?如果是这样,您可以先放置您的 char 过滤例程,然后一次性清理所有现有数据。这样您就不必每次提取时都进行扫描和清理。如果还有其他可能无效数据的来源,您可能只需要在每次提取时进行清理。 用户不仅是数据输入的来源。一些提要,一些来自 IBM z/OS 上的 IMS 和其他世界也提供输入。看起来我必须对这些提要进行参照完整性,并为他们提供脏数据报告和我的数据需求规范,以便他们可以清理他们的烂摊子!我想不出如果提要包含控制字符或 \0 (NULL) 会发生什么? 希望他们有能力/愿意收拾烂摊子。过去我做了一堆 Python 脚本来处理这种数据。如果它们对您没有帮助,您可能会考虑的一件事是将固定宽度文件转换为 XML 的脚本。然后另一个将 CSV 转换为 XML 等。使用 XML 作为您的常用格式。然后在导入之前在这些上运行 atlassian-xml-cleaner。 好的策略和建议,感谢您的建议!令人难以置信的是,有多少未经验证的脏数据存在,其中大部分几十年都未经检查!【参考方案2】:

使用默认管道卸载客户表;字符串搜索不存在的字符。 IE。 “~”

卸载到文件分隔符“~” 从客户中选择 *;

清理你的文件(或不清理) (vi 替换字符串):g/theoldstring/s//thenewstring/g) 或者 (unix 提示) sed 's/old-char/new-char/g' fileold > filenew

(一旦 clean id 个人将卸载文件中的“~”更改回“|”或“,”作为 csv 标准) 加载到源数据库。

【讨论】:

我不认为这是一个可行的解决方案,因为我在西班牙和美国语言环境的几个数据集中看到了字母 n 后面的波浪线!正如@Brian 所指出的,用户可以非常有创意并输入几乎所有可以想象的字符,所以最好的办法是对他们的数据输入进行验证以防止未来受到污染,然后清理现有的混乱! 恕我直言,这是对所述问题的最佳且唯一的答案,即使用数据中不存在的字符(如果您将问题重新定义为'字符或字符,并且可以使用 Informix 之外的其他内容)。如果您需要清理数据,那就是另一个问题了。 Frank@ 你最后清理了现有的烂摊子。不是这个问题吗。我的选择是一个答案。如果 ~ 在文件中,No 将不起作用,这就是为什么我说找到一个不存在的字符。这种方法没有任何缺陷,我一直在使用它。 FWIW,我为你的回答 +1 了。【参考方案3】:

如果可以,请使用多字符分隔符。它仍然可能失败,但应该不太可能。

或者,在写入导出文件时转义分隔符(Informix 文档说“LOAD TABLE”通过在分隔符前面加上反斜杠来转义)。正确的 CSV 具有引用和转义,因此数据中是否包含逗号无关紧要,除非您的导出器和加载器无法处理正确的 CSV。

【讨论】:

我从来没有听说过任何数据库能够导入带有多字符分隔符的数据。 @Frank - Oracle 的 sqlplus,Sybase 的 bcp ......我们每天都在使用它们......你用过什么? Informix 是一个很好的数据库,你确定你检查过文档吗? @Frank - 自从我使用 Informix 工作以来,它一直处于等待状态......也许“从文件加载”不允许它......但至少它允许转义数据中的分隔符,这是 Sybase 的 bcp才不是。我不敢相信 Informix 不会让你这样做...... Informix 的其他批量加载实用程序呢? AFAICR,具有 DBLOAD、HPL 或其他实用程序和内置 SQL 语句的 Informix 版本均不允许多个 DBDELIMITER 字符。 在我的情况下,最好在卸载之前清理源数据。这样我就不必推出可能有风险的清洁工具了。

以上是关于哪个字符最适合用作 ETL 的分隔符?的主要内容,如果未能解决你的问题,请参考以下文章

分隔多个正则表达式的最佳分隔符

哪个ETL最适合Hbase

在 Javadoc 中应该使用哪个标签作为段落分隔符?

无题3

反斜杠零分隔符 '\0'

我应该如何检测文本文件中使用了哪个分隔符?