| 功能 | JSON | JSONB |
|---|---|---|
| 存储格式 | 字符串原文存储 | 解析后的二进制 |
| 全文索引 | 不支持 | 支持 |
| 保留空白符 | 保留 | 不保留 |
| 保留键的顺序 | 保留 | 不保留 |
| 保留重复键 | 保留 | 不保留 |
CREATE TABLE product (
id INTEGER NOT NULL PRIMARY KEY,
product_name VARCHAR(100),
attributes JSONB
);
INSERT INTO product (id, product_name, attributes)
VALUES (1, '椅子','{"color":"棕色", "material":"实木", "height":"60cm"}');
INSERT INTO product (id, product_name, attributes)
VALUES (2, '沙发椅', '"color":"白色:50cm}');
SQL 错误 [22P02]: ERROR: invalid input syntax for type json
详细:Expected end of input, but found ":".
位置:71
在位置:JSON data, line 1: "color":...
Error position: line: 2 pos: 70
INSERT INTO product (id, product_name, attributes)
VALUES (
2,
'桌子',
'{"color":"黑色", "material":"金属", "drawers":[{"side":"左侧", "height":"30cm"}, {"side":"右侧", "height":"40cm"}]}'
);
INSERT INTO product (id, product_name, attributes)
VALUES (
3,
'茶几',
'{"color":"棕色", "material":["金属", "实木"]}'
);
SELECT jsonb_build_object('color', '黑色', 'material', '塑料');
jsonb_build_object |
---------------------------------+
{"color": "黑色", "material": "塑料"}|
INSERT INTO product (id, product_name, attributes)
VALUES (4, '小型桌子', JSONB_BUILD_OBJECT('color', '黑色', 'material', '塑料'));
json_build_object
to_json 以及 to_jsonb
array_to_json
row_to_json
json_build_array 以及 jsonb_build_array
json_object 以及 jsonb_object
SELECT id, product_name, attributes
FROM product;
id|product_name|attributes |
--+------------+------------------------------------------------------------------------------------------------------------------+
1|椅子 |{"color": "棕色", "height": "60cm", "material": "实木"} |
2|桌子 |{"color": "黑色", "drawers": [{"side": "左侧", "height": "30cm"}, {"side": "右侧", "height": "40cm"}], "material": "金属"}|
3|茶几 |{"color": "棕色", "material": ["金属", "实木"]} |
4|小型桌子 |{"color": "黑色", "material": "塑料"} |
SELECT id, product_name, attributes -> 'color' AS color
FROM product;
id|product_name|color|
--+------------+-----+
1|椅子 |"棕色" |
2|桌子 |"黑色" |
3|茶几 |"棕色" |
4|小型桌子 |"黑色" |
SELECT id, product_name, attributes -> 'color' AS color
FROM product;
id|product_name|color|
--+------------+-----+
1|椅子 |棕色 |
2|桌子 |黑色 |
3|茶几 |棕色 |
4|小型桌子 |黑色 |
SELECT id, product_name, attributes ->> 'height' AS height
FROM product;
id|product_name|height|
--+------------+------+
1|椅子 |60cm |
2|桌子 | |
3|茶几 | |
4|小型桌子 | |
SELECT id, product_name, attributes ->> 'drawers' AS drawers
FROM product
WHERE id = 2;
id|product_name|drawers |
--+------------+--------------------------------------------------------------------+
2|桌子 |[{"side": "左侧", "height": "30cm"}, {"side": "右侧", "height": "40cm"}]|
SELECT id, product_name, attributes -> 'drawers' -> 0 AS drawer1
FROM product
WHERE id = 2;
id|product_name|drawer1 |
--+------------+--------------------------------+
2|桌子 |{"side": "左侧", "height": "30cm"}|
SELECT id, product_name,
attributes #> '{drawers, 1}' AS drawer1,
attributes #>> '{drawers, 1}' AS drawer1_text
FROM product
WHERE id = 2;
id|product_name|drawer1 |drawer1_text |
--+------------+--------------------------------+--------------------------------+
2|桌子 |{"side": "右侧", "height": "40cm"}|{"side": "右侧", "height": "40cm"}|
SELECT id, product_name, attributes
FROM product
WHERE attributes = '{"color":"棕色", "material":"实木", "height":"60cm"}';
id|product_name|attributes |
--+------------+---------------------------------------------------+
1|椅子 |{"color": "棕色", "height": "60cm", "material": "实木"}|
SELECT id, product_name, attributes
FROM product
WHERE attributes = '{"color":"棕色"}';
id|product_name|attributes|
--+------------+----------+
SELECT id, product_name, attributes
FROM product
WHERE attributes ->> 'color' = '棕色';
id|product_name|attributes |
--+------------+---------------------------------------------------+
1|椅子 |{"color": "棕色", "height": "60cm", "material": "实木"}|
3|茶几 |{"color": "棕色", "material": ["金属", "实木"]} |
SELECT id, product_name, jsonb_each(attributes)
FROM product;
id|product_name|jsonb_each |
--+------------+------------------------------------------------------------------------------------------------+
1|椅子 |(color,"""棕色""") |
1|椅子 |(height,"""60cm""") |
1|椅子 |(material,"""实木""") |
2|桌子 |(color,"""黑色""") |
2|桌子 |(drawers,"[{""side"": ""左侧"", ""height"": ""30cm""}, {""side"": ""右侧"", ""height"": ""40cm""}]")|
2|桌子 |(material,"""金属""") |
3|茶几 |(color,"""棕色""") |
3|茶几 |(material,"[""金属"", ""实木""]") |
4|小型桌子 |(color,"""黑色""") |
4|小型桌子 |(material,"""塑料""") |
jsonb_each_text
json_each 以及 json_each_text
json_array_elements 以及 json_array_elements_text
jsonb_array_elements 以及 jsonb_array_elements_text
SELECT id, product_name, jsonb_object_keys(attributes)
FROM product;
id|product_name|jsonb_object_keys|
--+------------+-----------------+
1|椅子 |color |
1|椅子 |height |
1|椅子 |material |
2|桌子 |color |
2|桌子 |drawers |
2|桌子 |material |
3|茶几 |color |
3|茶几 |material |
4|小型桌子 |color |
4|小型桌子 |material |
SELECT id, product_name, attributes
FROM product
WHERE attributes ? 'drawers' = true;
id|product_name|attributes |
--+------------+------------------------------------------------------------------------------------------------------------------+
2|桌子 |{"color": "黑色", "drawers": [{"side": "左侧", "height": "30cm"}, {"side": "右侧", "height": "40cm"}], "material": "金属"}|
UPDATE product
SET attributes = attributes || '{"width":"100cm"}'
WHERE id = 1;
SELECT *
FROM product
WHERE id = 1;
id|product_name|attributes |
--+------------+---------------------------------------------------------------------+
1|椅子 |{"color": "棕色", "width": "100cm", "height": "60cm", "material": "实木"}|
UPDATE product
SET attributes = jsonb_insert(attributes, '{"weight"}', '"1kg"')
WHERE id = 3;
SELECT *
FROM product
WHERE id = 3;
id|product_name|attributes |
--+------------+----------------------------------------------------------+
3|茶几 |{"color": "棕色", "weight": "1kg", "material": ["金属", "实木"]}|
UPDATE product
SET attributes = jsonb_set(attributes, '{height}', '"75cm"')
WHERE id = 1;
SELECT *
FROM product
WHERE id = 1;
id|product_name|attributes |
--+------------+---------------------------------------------------------------------+
1|椅子 |{"color": "棕色", "width": "100cm", "height": "75cm", "material": "实木"}|
UPDATE product
SET attributes = NULL
WHERE id = 4;
SELECT *
FROM product
WHERE id = 4;
id|product_name|attributes|
--+------------+----------+
4|小型桌子 | |
UPDATE product
SET attributes = attributes - 'height'
WHERE id = 1;
SELECT *
FROM product
WHERE id = 1;
id|product_name|attributes |
--+------------+---------------------------------------------------+
1|椅子 |{"color": "棕色", "width": "100cm", "material": "实木"}|
UPDATE product
SET attributes = jsonb_set_lax(attributes, '{"width"}', null, false, 'delete_key')
WHERE id = 1;
SELECT *
FROM product
WHERE id = 1;
id|product_name|attributes |
--+------------+---------------------------------+
1|椅子 |{"color": "棕色", "material": "实木"}|
WITH RECURSIVE t AS (
SELECT 10 n, '产品'||10 product_name, '{"color": "棕色", "height": "60cm", "material": "实木"}' attr
UNION ALL
SELECT n+1, '产品'||n+1, '{"color": "棕色", "height": "60cm", "material": "实木"}'
FROM t WHERE t.n<10000
)
INSERT INTO product
SELECT n, product_name, attr::jsonb FROM t;
EXPLAIN
SELECT id, product_name, attributes
FROM product
WHERE attributes @> '{"color":"黑色"}';
QUERY PLAN |
--------------------------------------------------------+
Seq Scan on product (cost=0.00..258.93 rows=1 width=78)|
Filter: (attributes @> '{"color": "黑色"}'::jsonb) |
CREATE INDEX idx_product_attributes ON product USING GIN(attributes);
EXPLAIN
SELECT id, product_name, attributes
FROM product
WHERE attributes @> '{"color":"黑色"}';
QUERY PLAN |
------------------------------------------------------------------------------------+
Bitmap Heap Scan on product (cost=20.00..24.01 rows=1 width=78) |
Recheck Cond: (attributes @> '{"color": "黑色"}'::jsonb) |
-> Bitmap Index Scan on idx_product_attributes (cost=0.00..20.00 rows=1 width=0)|
Index Cond: (attributes @> '{"color": "黑色"}'::jsonb) |
原文作者:SQL编程思想;如有侵权,请联系管理员删除。