为什么PostgreSQL以自己的格式存储十六进制数据?

时间:2016-04-07 13:47:13

标签: postgresql

我无法理解PostgreSQL以自己的格式存储data的原因

  

" hex" format将二进制数据编码为每字节2个十六进制数字,最重要的是半字节数字。整个字符串前面是序列\ x(以区别于转义格式)。

它是不是意味着它不简单hex并且不可能简单地将此hex转换为byte类型,我应该编写PostgreSQL十六进制格式的解析器?

2 个答案:

答案 0 :(得分:1)

客户端驱动程序通常会为您进行bytea转换,为您提供类似byte[]的Java语言数据类型。电汇上bytea的表示通常不会引起您的注意。唯一真正重要的是你在SQL文本中使用bytea文字,而不是将它们作为绑定参数发送。

无论如何,它正常的十六进制,它只有一个\x前缀。因此,如果您需要手动执行此操作,那么“解析”完全是微不足道的。例如。在Python中

r'\x736f6d65737472696e67'[2:].decode("hex")

\x前缀的原因主要是历史性的。 PostgreSQL过去常常使用bytea数据的八进制转义格式。当格式更改为十六进制时 - 为了使客户端更容易使用和使用它并使其更紧凑 - 客户端必须能够告诉数据的格式。从{{1}开始绝不会出现在八进制(“转义”)格式文字中,任何以\x开头的字符串必须是十六进制bytea文字。从客户端接收数据时更为重要,客户端可能发送\xhex样式文字,服务器必须能够分辨哪个是哪个。

我们可能只需要所有客户端都使用服务器指定的格式。但这会破坏使用escape的所有旧客户端的兼容性。就个人而言,我认为这正是我们应该做的,并要求使用旧客户的人设置bytea或其他东西。但事情并非如此。设置bytea_format = escape控制服务器发送的格式,但它仍然将两种格式都理解为输入。这样可以更轻松地与旧客户端和脚本进行互操作。从理论上讲。

在实践中,许多老客户盲目地解释了服务器发送的十六进制文字,就好像它们是转义格式一样,即使它们是无效的;他们会忽略反斜杠或将其视为字面反斜杠。因此,在加载时,它们往往会损坏bytea数据,然后再次保存。正是我们想要避免的。

答案 1 :(得分:-2)

令我感到惊讶的是,获得如此好评的数据库系统是如此......在这方面很糟糕。例如,为了存储单字节值123,它应该将位序列00100100存储在单个字节中,而是发生以下情况:

123由十六进制7B表示,并以两个字节存储:00110111 01000010

使用十六进制/文本查看器检查数据文件确认了这一点。对于与数据库交互的程序员来说,这意味着他们不能只将字节流发送到数据库,但是他们总是需要将其编码为字符串表示。这让你想知道为什么要使用bytearray字段类型而不是仅仅使用utf-8甚至是latin-1 varchar。