在Postgresql中存储原始IMAP获取的电子邮件的数据类型是什么?

时间:2017-07-18 19:42:55

标签: postgresql email imap

我需要在从数据库中的IMAP中提取电子邮件后立即存储电子邮件,以便以后处理。我使用FETCH请求提取邮件,并使用BODY.PEEK[]返回数据。

根据我的理解,所有IMAP消息都以US-ASCII的形式返回(邮件服务器仅接受该消息),但我可能错了。

我的选择(按照我认为的顺序):

  • US-ASCII文本列
  • BYTEA
  • BLOB

我正在考虑使用US-ASCII,但我担心编码有问题,我不知道是否有错误" IMAP服务器没有返回us-ascii邮件。 另一种选择是Bytea,但我读到你必须处理编码,所以我不确定与US-ASCII相比有哪些优势/劣势。 BLOB是原始的,我不确定它在这种情况下提供的问题。我假设我必须处理字节到字符串的转换。

推荐的数据类型是什么?

2 个答案:

答案 0 :(得分:2)

对于电子邮件这样的小物件,我觉得Bytea会更好。存储和处理是不同的,因为你的对象会变小,看起来像Bytea会更好地处理。有关Microolap的两者的比较,请参阅here。这不是你问题的完整答案,但可能会从列表中删除一个选项。

答案 1 :(得分:1)

你做出了非常无根据的假设,即你可以避免处理编码。

你不能。

您是否使用lob,bytea或text列,您认为只包含7位邮件...邮件只是任意二进制数据。你不知道它的文本编码。在实践中,邮件客户端永远使用8位编码;符合标准的MIME引用可打印,或者通常只是原始的8位文本。

甚至已知一些客户端包括包含空(零)字节的完整8位MIME段。 PostgreSQL不会在text列中容忍它。

但即使对于使用兼容MIME,引用可打印转义文本正文等的客户端...邮件可能包含非ASCII字符,它们只是被转义。对这些进行索引并忽略转义会产生奇怪和错误的结果。此外,附件通常是任意base64数据。将其作为文本索引完全没有意义。然后是所有HTML主体,多部分/替代段,CSS等......

在处理电子邮件时,假设客户端或服务器可能出错的任何内容,都会出错。对于存储,请将电子邮件视为未知编码的原始字节。这正是bytea的用途。

如果你想用邮件做任何,你需要一个可以提取MIME部分的防御性MIME解析器,应对破坏的部分等。它需要检查声明的编码(如果有的话)对实际的mime-part主体,如果没有声明编码或者声明的编码明显错误,则猜测编码。它必须处理各种伪造的MIME结构和内容;引用可打印的主体,它们不是真正引用的可打印的,以及所有这些。

因此,如果你计划索引这封电子邮件,那绝对不像“创建全文索引并快乐地继续”那样简单。问题不是如果它会失败,而

就个人而言,如果我必须这样做(并且我不愿意选择),我会将原始电子邮件存储为bytea。然后,对于搜索,我将其分解为MIME部分,检测类似文本的部分,执行编码检测和取消引用等,并将解码和清理的文本主体注入到单独的表中以进行文本索引。

有一些有用的Perl模块可以通过plperlu使用,但我可能会在外部脚本/工具中使用它。然后,您可以选择MIME处理器,语言等。