【问题标题】:Querying a PostgreSQL multi-dimensional array data type in Rails 4在 Rails 4 中查询 PostgreSQL 多维数组数据类型
【发布时间】:2013-06-21 21:18:48
【问题描述】:

我正在使用 PostgreSQL 多维数组来模拟哈希数组,并且我正在寻找一种方法来通过该数组中的键值对来定位记录,例如 ["key1","value1"] .一个示例数组是:

[ ["key1","value1"], ["key2","value2"] ]

在我的情况下,这些键是语言,并且一个键可能会出现不止一次。

在 Rails 4 中使用 PostgreSQL 索引通过键值对定位记录是否有有效的方法?

编辑:修正错字

【问题讨论】:

  • 你可以使用扩展吗?然后查看 Hstore 扩展 - 这正是你想要的 - stackoverflow.com/questions/13766300/hstore-and-rails
  • 我查看了 Hstore,但正如 Craig 所说,它只支持单级键,并且由于键冲突,我需要返回一个数组,例如 { "key1" => ["value1 ", "value2"] }.
  • 寻找复杂的存储解决方案而不是数据库字段和表有什么特别的原因吗?
  • Denis:我有一个必须是可审计的表,而且每个区域都需要 slug。我正在尝试创建一个不需要额外表来简化与审计要求的交互的 slugging 库,但这可能是一条死胡同。
  • @AndreasSæbjørnsen 单字段为您提供了审计术语中两级表所没有的什么?无论哪种方式,您都有一个事务可以在表更改时使用触发器向审计表添加一个或一组更改。

标签: postgresql ruby-on-rails-4 rails-postgresql


【解决方案1】:

我正在使用 PostgreSQL 多维数组来模拟哈希数组

这两件事并不是真的很相似,我不建议尝试使用多维数组来建模嵌套哈希。

Pavel 说得很对,hstore 可能更接近您想要的,而且它也是可索引的。但是,当前版本的 hstore(在 Pg 9.3 和更早版本中)仅支持单级密钥;它是一个字典/哈希,只能包含标量字符串值。 PostgreSQL 9.4 的 hstore 计划增强功能有望带来多级嵌套和 JSON 语法兼容性。

普通表

您可以使用边缘列表和递归 CTE 对任意深度的键/值链(和树/图)进行建模,但这可能比您真正想要的复杂得多。

如果您只需要一个固定的两级键/值列表,只需使用列出两个键级的表即可:

CREATE TABLE twolevel(key1 text, key2 text, thevalue text not null, PRIMARY KEY(key1,key2));

这让您可以限制重复的密钥对,这很好。

您还可以使用两个具有外键关系的表。如果需要,这会为您提供级联删除,因此删除顶级键会删除所有子级键和关联值。不过,使用单表方法很容易做到这一点。

除非您有充分的理由不这样做,否则请使用这两种方法之一。

Hstore 为文本

在扩展 hstore 可用之前,一种选择是存储嵌套 hstore 字段的文本表示。这既不美观也不高效,但它可能比尝试搜索多维数组更好。

CREATE TABLE nested_hstore(id integer, blah hstore);

insert into nested_hstore(id, blah) values 
(1, hstore( ARRAY['key1','key2'], ARRAY['"key1.1"=>"value1.1", "key1.2"=>"value1.2"', '"key2.1"=>"value2.1", "key2.2"=>"value2.2"']::hstore[]::text[]));

测试:

regress=> select (blah->'key1')::hstore->'key1.1' from nested_hstore ;
 ?column? 
----------
 value1.1
(1 row)

因为每次都必须解析 hstore,所以它不会超快,而且您不会在第二级获得通常的索引优势。不过,如果您真的需要字段中的两级哈希,它仍然是一个选择。

hstore 值表

你可以很合理地把这两者结合起来。

CREATE TABLE twolevel(key1 text, level2keyvalues hstore);

不过,这对我来说似乎很丑;我宁愿以一种或另一种方式保持一致。

SQL/XML

另一种选择是使用 SQL/XML,您可以沿着任意 XPATH 表达式对其进行索引。同样,这似乎有点太复杂了。

【讨论】:

  • 我很难对 EdgeList 和递归 CTE 做出明智的选择,因为我对它们没有太多经验。但是,您说得对,因为它的复杂性,它似乎是一个不受欢迎的解决方案。也许我被困在使用多个数组,每种语言一个?这也是不可取的。
  • @AndreasSæbjørnsen 添加了一些细节。基本上我认为您应该为此使用普通表。
  • 我最终按照您的建议使用了更传统的模式设计。在这种情况下,hstore 和数组功能的当前实现似乎没有那么有用。
  • @AndreasSæbjørnsen 我倾向于同意。如果支持嵌套和 json 语法的 v2 hstore 工作顺利,那么希望这会改变,也许在 9.5...
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-04-10
  • 1970-01-01
  • 1970-01-01
  • 2015-07-04
  • 1970-01-01
  • 2019-03-28
  • 1970-01-01
相关资源
最近更新 更多