PostgreSQL在JSONB字段对象_array_上的视图(带有索引)

问题描述 投票:0回答:1

问题

您如何基于JSONB字段对象array适当的索引来创建PostgreSQL视图?下面的示例。

  1. 从概念上讲,与Views和JSONB数组一起使用时应如何应用索引编制?
  2. 创建相关索引的正确语法是什么?
  3. 示例视图是否给出了正确/最佳的方式来构造此用例的视图?

示例

表格

CREATE TABLE "ProductLists"
(
    id uuid NOT NULL DEFAULT gen_random_uuid(),
    listName text NOT NULL
    productIds jsonb NOT NULL DEFAULT '[{ productId:0 }]'::jsonb,
)

查看(可以更改)

具有以下视图:

SELECT "ProductLists".id AS listId,
    jsonb_array_elements("ProductLists".productIds) ->> 'productId'::text AS productId
   FROM "ProductLists";

因素

  • JSONB根是一个数组,而不是一个对象(在大多数索引示例中并非如此)
  • 可能有数百万个ProductList项
  • 每个列表中的productId数量通常少于100
  • 该表将同时具有较高的读写次数
  • 视图SQL示例可能不是最佳选择,可以更改

感谢您的输入!

postgresql indexing view jsonb
1个回答
0
投票

jsonb列上的GIN索引将支持several JSON operators。其中之一是@>运算符,它也可用于JSON数组。

以下索引:

create index on product_list using gin (product_ids);

可能会利用上述索引的查询看起来像这样:

select *
from product_list
where product_ids @> '[{"productId": 42}]'::jsonb;

您的建议视图无法利用索引,因为JSONB列不属于该视图,因此必须向下推JSON列的条件。

您可以在视图中使用索引的唯一方法是在其中包含JSON列:

create view normalized_list
as
SELECT pl.id AS list_id,
       t.product_id, 
       pl.product_ids
FROM product_list pl
   CROSS JOIN jsonb_array_elements(pl.product_ids) ->> 'id' AS t(product_id)
;

这样的查询:

select id, product_Id
from normalized_list
where product_ids @> '[{"id":42}]'::jsonb;

将利用GIN索引。


请注意,如果only要以非规范化方式存储ID,则本机整数数组(product_ids int[])会更高效,并使表大大变小]

© www.soinside.com 2019 - 2024. All rights reserved.