【问题标题】:How to store a multi array of tuples in PostgreSQL如何在 PostgreSQL 中存储多个元组数组
【发布时间】:2020-03-08 18:08:05
【问题描述】:

我有一个类似[[(Double,Double)]] 的数组。它是一个多维元组数组。

这是我永远不会查询的数据,因为它不需要查询。只有在客户端这样才有意义。我正在考虑将整个内容存储为字符串,然后将其解析回多数组。

考虑到我最多可以有 20 个数组和 4 个最大内部数组,每个数组都有一个 2 Double 的元组,这会是一个好方法吗?解析会非常昂贵吗?
我将如何检查哪种方法更好,以及将其作为多维数组存储在 PostgreSQL 中是否更好?
我将如何存储它?

【问题讨论】:

  • "解析会非常昂贵" - 因为您会在 postgres 数据库之外执行此操作,所以只有您选择的语言/框架/技术中的基准可以判断。还要测量序列化开销。
  • 我看不出有任何理由将其存储在 postgres 中的实际数组中,这有望为其选择最佳内存布局。除非您可以在自定义序列化后充分利用压缩。也就是说,20*4*2 是一个非常小的数组,所以除非这些数组有数千行,否则您可能会don't need to worry anyway
  • 我将如何存储一个多数组的元组。我可以存储多个 Double 数组,但我会存储 (Double,Double)
  • 就像 Erwin 如下所示 :-) 或者,作为三维数组,其中第三维的大小为 2。
  • 我认为这不会有什么不同。复合类型可能更难使用,但这主要取决于您的工具和技术。

标签: postgresql parsing multidimensional-array database-design tuples


【解决方案1】:

要存储复合类型的数组(具有任何嵌套级别),您需要使用已注册的基类型。你可以有一个定义行类型的表,或者只是显式地创建类型:

CREATE TYPE dd AS (a float8, b float8);

这里有一些方法可以构建你的二维数组:

SELECT ARRAY [['(1.23,23.4)'::dd]]
     , (ARRAY [['(1.23,23.4)']])::dd[]
     , '{{"(1.23,23.4)"}}'::dd[]
     , ARRAY[ARRAY[dd '(1.23,23.4)']]
     , ARRAY(SELECT ARRAY (SELECT dd '(1.23,23.4)'));

相关:

请注意,Postgres 数组类型dd[] 可以存储具有任何嵌套级别的值。见:

这是否比将字符串文字存储为text 更有效很大程度上取决于您的用例细节。

  • 数组类型占用 24 字节的开销加上元素值的通常存储大小。
  • float8 (= double precision) 占用 8 个字节。文本字符串“1”在磁盘上占 2 个字节,在 RAM 中占 4 个字节。 text '123.45678' 在磁盘上占用 10 字节,在 RAM 中占用 12 字节。
  • 简单的text 的读取和写入速度比同等大小的数组类型要快一些。
  • 大的text 值会被压缩(自动),这有利于存储大小(尤其是重复模式) - 但会增加压缩/解压缩成本。

实际的 Postgres 数组在任何情况下都更干净,因为 Postgres 不允许存储非法字符串。

【讨论】:

  • 最后一行是什么意思? “无论如何,实际的 Postgres 更干净,因为 Postgres 不允许存储非法字符串。”我的用例是,当查询此数据时,它需要尽快位于客户端的该数组中。我在客户端使用 swift
  • 最后一行的意思是,任何人都不能在数据库中潜入非法数据——意外或恶意。
  • 那么对于我使用 dd 类型数组或字符串的用例,你会推荐什么。我在上面的评论中添加了我的用例,顺便说一句谢谢!
  • @j.doe 实现它们,并在重要的地方设置时间。然后在真实数据上运行。
  • @j.doe:在其核心使用另一个数组而不是复合类型的替代方法不需要自定义类型dd,从而使语法更简单。存储大小和性能应该相同。翻译成/从你的原始形式可能会贵一点。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-11-08
  • 1970-01-01
  • 1970-01-01
  • 2020-01-22
  • 2016-02-13
  • 2020-08-21
  • 2016-03-08
相关资源
最近更新 更多