浏览Postgres 9.4数据类型JSONB的文档时,我并不清楚如何对JSONB列进行更新。
JSONB类型和函数的文档:
http://www.postgresql.org/docs/9.4/static/functions-json.html
http://www.postgresql.org/docs/9.4/static/datatype-json.html
作为一个例子,我有这样一个基本的表结构:
CREATE TABLE test(id serial, data jsonb);
插入很容易,比如:
INSERT INTO test(data) values ('{"name": "my-name", "tags": ["tag1", "tag2"]}');
现在,我该如何更新“数据”列呢?这是无效的语法:
UPDATE test SET data->'name' = 'my-other-name' WHERE id = 1;
这是否被记录在我遗漏的某个地方?谢谢。
理想情况下,对于希望在关系数据库中操作的结构化常规数据,不要使用JSON文档。请使用规范化的关系设计。
JSON主要用于存储RDBMS中不需要操作的整个文档。相关:
带索引的JSONB vs. hstore
在Postgres中更新一行总是会写入整行的新版本。这就是Postgres的MVCC模型的基本原理。从性能的角度来看,更改JSON对象中的单个数据还是全部数据几乎无关紧要:必须写入该行的新版本。
因此手册中的建议是:
JSON data is subject to the same concurrency-control considerations as
any other data type when stored in a table. Although storing large
documents is practicable, keep in mind that any update acquires a
row-level lock on the whole row. Consider limiting JSON documents to a
manageable size in order to decrease lock contention among updating
transactions. Ideally, JSON documents should each represent an atomic
datum that business rules dictate cannot reasonably be further
subdivided into smaller datums that could be modified independently.
其要点是:要修改JSON对象中的任何内容,必须将修改后的对象分配给列。Postgres除了提供存储功能外,还提供了有限的方法来构建和操作json数据。自版本9.2以来,每个新版本的工具库都有了大幅增长。但基本原则仍然存在:你总是必须将一个完整的修改后的对象分配给列,并且Postgres总是为任何更新编写一个新的行版本。
使用Postgres 9.3或更高版本工具的一些技巧:
如何修改新的PostgreSQL JSON数据类型中的字段?
这个答案吸引的反对票和我在SO上的所有其他答案加起来一样多。人们似乎不喜欢这个想法:规范化设计对于规则数据更优越。Craig Ringer的这篇精彩的博客文章详细解释了这一点:
PostgreSQL反模式:不必要的json/hstore动态列
Laurenz Albe(与Craig和我一样是Postgres的官方贡献者)的另一篇博文:
PostgreSQL中的JSON:如何正确使用它