【问题标题】:Storing nested Hashes in PostgreSQL with Rails 4 (and Hstore)使用 Rails 4(和 Hstore)在 PostgreSQL 中存储嵌套哈希
【发布时间】:2013-09-22 14:13:20
【问题描述】:

我有一个 Rails 应用程序,它从 Google API 聚合了大量数据。我目前将 JSON 响应存储在 MongoDB 中(所以我的 Rails 应用程序同时具有 pg 和 mongo)。但是,今天我遇到了 PostgreSQL Hstore 扩展,我决定试一试。

很遗憾,我遇到了问题。 API 给出的 JSON 是多级深度的,因此JSON.parse 之后的 Ruby 哈希包含哈希,其中包含新的哈希。但是,Hstore 是字符串键/值存储,它只有 1 级深。所以第一个散列中的散列就变成了字符串。

我发现真正令人讨厌的 hack 是 eval 将哈希值转换为字符串:

eval("{ "foo" => "bar" }")

我不喜欢这样。关于做什么的任何提示?我应该继续使用 MongoDB 还是有更好的方法在 PG 中存储多级深度哈希?

【问题讨论】:

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


    【解决方案1】:

    您应该尝试对 Postgresql 使用 JSON 扩展。它会做你想做的事:验证和存储 JSON。最初 JSON 扩展是在 9.2 中添加的。 Postgres 9.3 为 JSON 扩展添加了更多特性,包括新的运算符和函数。 postgres 9.4 将具有对 JSON 的高级索引支持,因此您将通过此设置获得未来的保障。

    相关链接: http://www.postgresql.org/docs/9.3/static/functions-json.html http://wiki.postgresql.org/wiki/What's_new_in_PostgreSQL_9.3#JSON:_Additional_functionality

    【讨论】:

      【解决方案2】:

      Nested Hstore 是一个 gem,它支持 hstore 中的嵌套哈希(以及数组和其他类型),实现类似于 MongoDB 等文档存储的功能。它使用 hstore 和 JSON 序列化的混合。不过,它还没有在 Rails 4 上测试过。

      【讨论】:

      • 谢谢。为时已晚,但这个想法很好,很适合我的目的。
      【解决方案3】:

      作为 Hstore 状态的documentation,Hstore 中的键和值只是文本字符串。 Hstore 不能存储多级 json 对象,也不是为了那个目的。

      因此,为了简单起见,您不能通过简单地使用 Hstore 将 MongoDb 替换为 PostgreSQL。相反,您需要像在任何其他关系数据库中一样为每种对象创建表。如果您的对象架构非常动态,最好继续使用 MongoDB。

      【讨论】:

        【解决方案4】:

        作为问题的后续,似乎 Postgresql 9.4 提供了一些很棒的东西:

        1. Hstore 现在是嵌套的并支持数组,这意味着从简单的键值模型转变为基于文档的丰富模型。
        2. 对指定字段的 Hstore 访问速度很快(感谢二进制表示)
        3. Hstore 操作员可以使用 GiST 和 GIN 索引
        4. Json 用户可以使用功能性 GIN 索引并获得相当大的加速
        5. json可以使用Hstore的二进制表示

        source

        【讨论】:

          【解决方案5】:

          使用json数据类型来存储json,而不是hstore。

          【讨论】:

            【解决方案6】:

            如果您对将多级 json 转换为可以存储在 postgres 中的对象不感兴趣,您可以将所有内容粘贴到 postgres 的 text 字段中,如果您正在寻找,可以序列化/反序列化 json 字符串mongo 之外的多级键/值存储。

            如前所述,Hstore 不会做你想做的事。

            【讨论】:

            • 是的,我想我可以做到。但我真的很想在数据库中有字段,而不需要架构。
            • 那么 mongodb 适合你!
            • 另外,比存储json更好的是使用Rails serialize模型助手,它使用:text db字段,但是从Ruby Hash自动转换为文本,反之亦然。
            【解决方案7】:
            setting[:quizzes] # => "{:score=>true, :percent=>true, :weight=>true}"
            JSON.parse setting[:quizzes].gsub(/:(\w+)/){"\"#{$1}\""}.gsub('=>', ':')
            # => {"score"=>true, "percent"=>true, "weight"=>true}
            

            【讨论】:

            • 请通过描述您所做的以及它如何回答问题来解释此代码。这样提问者(和未来的读者)就不需要要求澄清了。
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2015-12-28
            • 1970-01-01
            • 2014-08-31
            • 2015-04-16
            • 2023-03-18
            • 2016-08-11
            • 2017-04-05
            相关资源
            最近更新 更多