【问题标题】:Postgres unique index on text array文本数组上的 Postgres 唯一索引
【发布时间】:2018-10-12 01:25:26
【问题描述】:

如何在文本数组列上添加唯一索引。

我的 Postgres 表中有一个包含部分的列。

 +----+-----------+
 | id |  sections |
 |----|-----------|
 |  1 |['A', 'B'] |
 +----+-----------+
 |  2 |['A', 'A'] |
 +----+-----------+

正如您在 id 2 中看到的那样,我可以插入两个具有相同文本的部分。我不想添加重复的文本。 我不想在我的专栏中有重复的部分。 有没有办法在文本数组上添加索引。

我看到了 int 数组的示例,但找不到 text 数组的任何内容

我不想创建新功能。我想使用 Postgres 中已有的函数。

【问题讨论】:

  • 您不能在数组上创建唯一索引以防止数组元素重叠。标准化你的模型,然后真的很容易
  • 您需要一个触发器来实现这一点,但这会很昂贵。将您的模型标准化为提到的@a_horse_with_no_name。
  • 您想禁止单行中的重复值吗?如上例所示,您不允许将 ['A', 'A'] 插入第 2 行,但允许将 ['A', 'B'] 插入。或者您是否想禁止添加包含 A 的数组的行,因为有一行包含 A 的数组?
  • 我想在单行中禁止重复值。编辑:实际上两者都可以。

标签: postgresql indexing constraints


【解决方案1】:

您可以像这样附加到部分列中并使用不同的元素取消嵌套:

update class set sections = array(
    select distinct unnest(
        array_append(
            (select section from class where id = 2), 'A'))
    where id = 2)

【讨论】:

    【解决方案2】:

    我喜欢 arays,但并不总是对表格进行规范化 :-)

    CREATE OR REPLACE FUNCTION is_not_unique(a int[]) RETURNS bool AS $f$
       SELECT array_upper(a, 1) = array_upper(
                   (
                    SELECT array_agg(DISTINCT u)
                      FROM unnest(a) AS u
              ), 1);
    $f$ LANGUAGE sql;
    
    CREATE TEMP TABLE a (a int[], CHECK (is_not_unique(a)));
    

    测试一下:

    # INSERT INTO a VALUES (ARRAY[1]);
    INSERT 0 1
    # INSERT INTO a VALUES (ARRAY[1, 2]);
    INSERT 0 1
    # INSERT INTO a VALUES (ARRAY[1, 1]);
    ERROR:  new row for relation "a" violates check constraint "a_a_check"
    DETAIL:  Failing row contains ({1,1}).
    

    【讨论】:

    • 对于整数,我实现了这个问题之前的解决方案。我正在寻找文本数组解决方案。感谢您的帮助:)
    • 文本也一样
    猜你喜欢
    • 2013-12-27
    • 2013-09-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-25
    • 2016-07-14
    相关资源
    最近更新 更多