sql >> データベース >  >> RDS >> PostgreSQL

PostgreSQLの一意の値が複数の列にまたがる

    残念ながら、これは単純な一意の制約/インデックスでは簡単に解決できません(それらで解決できる場合)。

    必要なのは、除外 制約衝突などに基づいて一部の行を除外する機能 。一意の制約は、特定の除外制約にすぎません(これらは、等式衝突に基づいています。 。

    したがって、理論的には、すべてのrow1を除外する必要があります。 、row2がすでに存在する場合 、この式が当てはまる場合:ARRAY[row1.cola, row1.colb] && ARRAY[row2.cola, row2.colb]

    このインデックスは可能性があります 仕事をする(現在はgistのみ) インデックスは除外制約をサポートします):

    ALTER TABLE table_name
      ADD CONSTRAINT table_name_exclusion
      EXCLUDE USING gist ((ARRAY[cola, colb]) WITH &&);
    

    しかし 残念ながら、配列のデフォルトの演算子クラスはありません(gistを使用します) )。 intarrayがあります モジュールintegerのみに1つ提供します 配列ですが、textには何もありません 配列。

    本当にこれを解決したい場合は、いつでもrange タイプ (例:隣接する-|-を使用しました uniqueでは処理できないすべてのケースを処理する演算子 )...

    -- there is no built-in type for text ranges neither,
    -- but it can can be created fairly easily:
    CREATE TYPE textrange AS RANGE (
      SUBTYPE = text
    );
    
    ALTER TABLE table_name
      ADD CONSTRAINT table_name_exclusion
      EXCLUDE USING gist ((textrange(least(cola, colb), greatest(cola, colb))) WITH -|-);
    
    -- the exclusion constraint above does not handle all situations:
    
    ALTER TABLE table_name
      ADD CONSTRAINT table_name_check
      CHECK (cola is distinct from colb); -- without this, empty ranges could be created,
                                          -- which are not adjacent to any other range
    
    CREATE UNIQUE INDEX table_name_unique
      ON table_name ((ARRAY[least(cola, colb), greatest(cola, colb)]));
         -- without this, duplicated rows could be created,
         -- because ranges are not adjacent to themselves
    

    ...しかし、恐れ入りますが、データベースを少しリファクタリングするだけで、元の問題をはるかに簡単に解決できる可能性があります。それは私たちに質問をもたらします:どのような問題、これで解決したいですか?




    1. VBAランタイムエラー'-2147467259(80004005)

    2. MYSQL検索結果

    3. 良いリレーショナルデータベースのチュートリアルはありますか?

    4. SQLite Group By