如何在Postgres 9.4中执行对JSONB类型列的更新操作

5 浏览
0 Comments

如何在Postgres 9.4中执行对JSONB类型列的更新操作

阅读Postgres 9.4的JSONB数据类型文档后,我并不立刻明白如何更新JSONB列。\nJSONB类型和函数的文档:\nhttp://www.postgresql.org/docs/9.4/static/functions-json.html\nhttp://www.postgresql.org/docs/9.4/static/datatype-json.html\n作为一个示例,我有这个基本的表结构:\n

CREATE TABLE test(id serial, data jsonb);

\n插入很容易,如下所示:\n

INSERT INTO test(data) values ('{"name": "my-name", "tags": ["tag1", "tag2"]}');

\n那么,我如何更新\"data\"列呢?下面的语法是无效的:\n

UPDATE test SET data->'name' = 'my-other-name' WHERE id = 1;

\n这个问题是否在我错过的地方有明确的文档记录?谢谢。

0
0 Comments

PostgreSQL 9.4中的JSONB类型的列无法直接执行更新操作,这引发了一个问题。然而,解决这个问题的方法是使用即将在9.5版本中引入的jsonb_set函数。这个函数是基于现有的jsonbx扩展开发的,而jsonbx扩展是可以在9.4版本中使用的。

另一个问题是在使用jsonb_build_object()函数时,由于x->key并不能返回键值对,所以无法正确地填充目标列。正确的方法是使用jsonb_set(target, path, jsonb_build_object('key',x->key))。

在PostgreSQL 9.5版本中,开发人员引入了jsonb_set函数来解决JSONB类型列无法直接执行更新操作的问题。这个函数基于已经存在的jsonbx扩展进行开发,而这个扩展可以在9.4版本中使用。另外,还需要注意在使用jsonb_build_object()函数时,要使用正确的方法来填充目标列。

0
0 Comments

如何在Postgres 9.4中执行对JSONB类型列的更新操作

在Postgres中,理想情况下,您不会使用JSON文档来存储要在关系数据库中操作的结构化、规则的数据。而是使用规范化的关系设计。

JSON的主要用途是存储不需要在关系数据库中进行操作的完整文档。更新Postgres中的一行始终会写入一个新版本的整个行。这是Postgres MVCC模型的基本原则。

因此,建议将JSON文档限制在可管理的大小,以减少更新事务之间的锁争用。理想情况下,每个JSON文档应该代表一个原子数据,业务规则要求不能合理地进一步细分为可以独立修改的较小数据。

要修改JSON对象中的任何内容,您必须将修改后的对象分配给列。Postgres提供了有限的工具来构建和操作JSON数据,除了存储功能之外。从Postgres 9.3版本开始,这些工具的功能已经大大增强。但原则保持不变:您始终必须将完整的修改后的对象分配给列,而Postgres始终会为任何更新写入新的行版本。

以下是使用Postgres 9.3或更高版本工具的一些技术:

- 如何修改PostgreSQL JSON数据类型中的字段?

- PostgreSQL反模式:不必要的json/hstore动态列

- PostgreSQL中的JSON:正确使用方法

这些建议和技术只涉及JSON类型,忽略了JSONB类型。

对于数据类型json和jsonb来说,这些建议和技术都适用。它们都存储JSON数据,jsonb以一种规范化的二进制形式进行存储,具有一些优点(和一些缺点)。对于在数据库内部进行大量操作的数据类型,无论是json还是jsonb,都不是很好的选择。没有任何文档类型是适合于在数据库内部进行大量操作的。尽管对于小型、结构不明确的JSON文档来说是可以的,但对于大型、嵌套的文档来说,那样做是愚蠢的。

需要注意的是,Postgres在每个版本中都改进了JSON支持,并且现在非常出色。对于特定的应用程序非常有用。但我的答案仍然完全适用,特别是对于这个问题所询问的“更新操作”,因为它涉及到文档类型的一个主要限制。对于规则数据来说,更合适的是使用一个更或多或少规范化的数据库模式中的适当列,这通常要更高效。这个原则不会改变。Postgres项目也是如此建议的,就像我上面引用的那样。

需要注意的是,这个回答只关注JSON类型,并忽略了JSONB类型。所以在使用JSONB类型时需要注意。

以上回答只回答了问题,没有添加额外的评论、意见或讨论。

0
0 Comments

问题的原因是Postgres 9.4版本不支持对JSONB类型的列执行更新操作。然而,可以通过创建一个临时修改版本的数据,并将该修改版本重新赋值给列来实现更新操作。以下是一些可用的解决方法:

1. 如果升级到Postgres 9.5版本,可以使用jsonb_set命令来执行更新操作。

2. 如果要更新JSONB列中的某个字段,可以使用jsonb_set函数,将要更新的字段路径和新的值作为参数传递给该函数。

3. 如果要替换JSONB列中的标签,可以使用jsonb_set函数,将要替换的标签路径和新的标签列表作为参数传递给该函数。

4. 如果要替换JSONB列中的第二个标签,可以使用jsonb_set函数,将要替换的标签路径和新的标签值作为参数传递给该函数。

5. 如果要在JSONB列中添加一个标签,可以使用jsonb_set函数,将要添加的标签路径和新的标签值作为参数传递给该函数,并将最后一个参数设置为true

6. 如果要删除JSONB列中的最后一个标签,可以使用#-操作符,将要删除的标签路径作为参数传递给#-操作符。

7. 如果要进行复杂的更新操作,可以使用jsonb_set函数和#-操作符的组合,对JSONB列进行多个操作。

在这些示例中,需要注意的是,实际上并没有直接更新JSON数据字段的单个属性。相反,是创建了一个临时的修改版本,并将该修改版本重新赋值给列。这样做的结果应该是相同的,但是了解这一点应该可以使复杂的更新操作更易理解。

对于一些特殊需求,比如删除特定值的标签,可以考虑使用存储过程或在应用程序语言中处理数据,然后再将其写回。

关于'{tags,999999999}'的用法,它是一个数组附加的技巧。如果使用{tags,0},表示的是"标签数组的第一个元素",可以为该元素赋一个新的值。通过使用一个较大的数字而不是0,可以将一个新元素添加到数组中,而不是替换数组中的现有元素。然而,如果数组中实际上有超过999,999,999个元素,这个操作将替换最后一个元素而不是添加一个新元素。

当JSONB包含子JSON时,可以通过使用->操作符来访问子JSON的子字段,并使用jsonb_set函数来更新或添加子字段的值。但是,需要确保传递给jsonb_set函数的参数正确。如果出现函数不存在的错误,可能是由于传递给jsonb_set函数的参数类型不正确导致的。需要确保将正确的字段路径和值作为参数传递给函数。

要在Postgres 9.4中执行JSONB列的更新操作,可以使用jsonb_set函数和#-操作符的组合,或者考虑升级到Postgres 9.5以获得更多的功能和更好的性能。

0