【发布时间】:2018-10-26 20:44:29
【问题描述】:
假设我们有一个 PostgreSQL 表 contacts,每条记录都有一堆带标签的电子邮件地址(标签和电子邮件对)——其中一个是“主要”。
这是这样存储的:
-
id主键 -
email文字 -
email_label文字 -
metadatajsonb-
emails数组 -
email文字 -
label文字
-
例如,一条记录可能类似于:
id: 1
email: 'a@a.com'
email_label: 'a'
metadata: {
"emails": [
{
"email": "b@b.com",
"label": "b"
},
{
"email": "c@c.com",
"label": "c"
}
]
}
鉴于这种存储模式,我们希望能够通过其任何电子邮件地址找到记录。
天真的查询看起来像:
SELECT id
FROM contacts
WHERE
email = 'my@email.com' OR
metadata -> 'emails' @> '[{"email": "my@email.com"}]'
有什么方法可以创建一个索引来显着加快这个操作?它需要自动更新以响应记录的变化,最好是跨文本列和嵌套列的索引JSONB 列。
此处的特定用例将能够通过电子邮件地址高效快速地进行查找,而无需彻底检查此结构或创建新的关系表。
我相信解决方案涉及使用 GIN 索引和 this question mentions jsonb_path_ops,但我不确定如何将所有部分组合在一起。
【问题讨论】:
标签: sql postgresql database-indexes