我有一个Rails模型,它有一个类型为"json"的数据库列:

create_table "games", force: true do |t|
  t.json     "game_board"
  t.datetime "created_at", null: false
  t.datetime "updated_at", null: false
end

太棒了现在我该如何使用它?它真的像treating the field like a Hash一样简单吗?

self.game_board[:player1] = 1
self.game_board[:cards] = cards.to_hash

如果我写这篇文章,一切都会像预期的那样工作吗?所以在future 的客户端API调用中,我可以做到这一点:

self.game_board[:player] # And get back the 1 that I put here before

那么性能呢?即使从未读取该字段,是否每次都会对整个game_board进行反序列化?每次我更改"哈希"的一部分时,是否会重新写入该字段(在数据库写入时)

推荐答案

是的,ActiveRecord允许将Postgres的json个字段简单地用作其模型中的散列.然而,有几件事需要考虑:

  1. 初始化时哈希值可能为空

  2. 在JSON中,所有键都是字符串


self.game_board         ||= {}
self.game_board[:player1] = 1
self.game_board[:cards]   = cards.to_hash

# after reload from database (access via String-key):
self.game_board['player1']  # And retrieve value 1 (that we put here before)


  1. 是的,每次ActiveRecord从数据库读取一个条目并创建一个模型实例时,JSON字段都会被非序列化为哈希.但是,如果您认为这会影响应用程序的性能,那么您应该在需要时使用文本字段并序列化/反序列化JSON/哈希,或者更好的是,完全不要使用ActiveRecord.通过创建大量类和使用神奇的方法,ActiveRecord产生了大量开销,因此您不必担心JSON的反序列化.便利是有代价的.

  2. 是的,每次更改哈希中的值时,(整个)JSON字段都会被替换并更新为新的序列化版本

    • 即使在Postgres本身(不仅在ActiveRecord中),对某些JSON元素执行更新的可能性直到现在都不存在.Compare this Stackoverflow-question
    • 一般来说,JSON字段应该以固定的 struct 使用,或者至少以可管理的大小使用,并且字段类型不应该是像MongoDB中那样的文档存储.Compare the Postgres documentation

Postgresql相关问答推荐

PostgreSQL:计数多列中的唯一值

org.postgresql. util.PSQLException:使用docker + docker—compose + kafka + springboot时try 连接失败

Postgres 13.8 -如何在对数据执行窗口操作时返回所有行

可以向判断枚举值的SQL列添加约束吗?

列索引8上的扫描错误,名称已复制:不支持扫描,正在存储驱动程序.值类型[]uint8到类型*[]*bool

有没有一种方法可以在参数中添加密码,并在批处理文件中需要时自动获取密码?

在Postgre中的链接服务器上执行远程查询

PostGresql :正则表达式 Select 其中只有一个正斜杠的行

错误:用户需要系统密码:postgres

找出两个表之间的差异

Postgres >= 和 <= 具有特殊字符的行为

我应该使用哪个 postgresql 包?

OpenShift:如何从我的 PC 连接到 postgresql

在 postgres 中Decode解码相似的函数

如何确定 NULL 是否包含在 Postgres 的数组中?

用于更改 postgresql 用户密码的 bash 脚本

根据 Helm 图表设置值

在 postgres 中插入语句用于没有时区 NOT NULL 的数据类型时间戳,

使用 RPostgreSQL 写入特定模式

PostgreSQL/JDBC 和 TIMESTAMP 与 TIMESTAMPTZ