【问题标题】:unique index on embedded json object嵌入 json 对象的唯一索引
【发布时间】:2014-11-15 12:57:11
【问题描述】:

我现在正在测试 Postgresql 9.4 beta2。我想知道是否可以在嵌入式 json 对象上创建唯一索引?

我创建一个表名products:

CREATE TABLE products (oid serial primary key, data jsonb)

现在,我尝试将 json 对象插入数据列。

{
    "id": "12345",
    "bags": [
        {
            "sku": "abc123",
            "price": 0,
        },
        {
            "sku": "abc123",
            "price": 0,
        }
    ]
}

但是,我希望 sku 的包包是独一无二的。这意味着无法将 json 插入到产品表中,因为 sku 在这种情况下不是唯一的。

我尝试创建如下所示的唯一索引,但失败了。

CREATE UNIQUE INDEX product_sku_index ON products( (data->'bags'->'sku') )

有什么建议吗?

【问题讨论】:

  • 唯一索引在这里不起作用,因为只有一个值。您不能将多个条目添加到单行的索引中。为此,您需要一个 check 约束 - 但它只能在单行上运行。没有简单的方法可以说“我希望这个子字段在所有行中的所有 json 对象中都是唯一的”。
  • 请不要将oid 用于您自己的列。这是 Postgres 使用的内部名称,会引起很多混乱(如果不是问题)
  • 我想我必须改变我的设计。谢谢你帮助我。

标签: json postgresql indexing unique-index postgresql-9.4


【解决方案1】:

由于多种原因,您在表达式上创建UNIQUE INDEX 的尝试注定会失败。

CREATE UNIQUE INDEX product_sku_index ON products( (data->'bags'->'sku') )

第一个也是最微不足道的就是...
data->'bags'->'sku'
引用任何东西。您可以使用

引用数组的 first 元素
data->'bags'->0->>'sku'

或更短:

data#>>'{bags,0,sku}'

但该表达式只返回数组的第一个值。
您的定义:“我希望包的 sku 是独一无二的” .. 不清楚。您希望sku 的值是唯一的吗?在data 列中的一个 JSON 对象中还是在所有 json 对象中?还是要将数组限制为带有 sku 的单个元素?

无论哪种方式,这些目标都不能通过简单的UNIQUE 索引来实现。

可能的解决方案

如果您希望 sku valuesdata->'bags' 中的所有 json 数组中是唯一的,有一种方法。取消嵌套数组并将所有单独的 sku 值写入具有唯一(或 PK)约束的简单辅助表中的分隔行:

CREATE TABLE prod_sku(sku text PRIMARY KEY);  -- PK enforces uniqueness

此表可能对其他用途有用。
下面是一个完整的代码示例,用于解决与普通 Postgres 数组非常相似的问题:

仅采用取消嵌套技术。而不是:

DELETE FROM hostname h
USING  unnest(OLD.hostnames) d(x)
WHERE  h.hostname = d.x;

...

INSERT INTO hostname(hostname)
SELECT h
FROM   unnest(NEW.hostnames) h;

用途:

DELETE FROM prod_sku p
USING  jsonb_array_elements(NEW.data->'bags') d(x)
WHERE  p.sku = d.x->>'sku';

...

INSERT INTO prod_sku(sku)
SELECT b->>'sku'
FROM   jsonb_array_elements(NEW.data->'bags') b

那个的详细信息:

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-07-22
    • 1970-01-01
    • 1970-01-01
    • 2017-09-07
    • 2023-04-02
    • 2022-07-15
    • 2021-12-06
    相关资源
    最近更新 更多