sql >> Databáze >  >> RDS >> PostgreSQL

Jedinečná hodnota PostgreSQL s více sloupci

Bohužel to nelze snadno vyřešit pomocí jednoduchých jedinečných omezení / indexů (pokud to lze s nimi vůbec vyřešit).

Co potřebujete, je výjimka omezení :možnost vyloučit některé řádky na základě něčeho jako kolize . Jedinečná omezení jsou pouze specifická omezení vyloučení (jsou založena na kolizích rovnosti ).

Teoreticky tedy stačí vyloučit každý row1 , kde již existuje row2 , pro které platí tento výraz:ARRAY[row1.cola, row1.colb] && ARRAY[row2.cola, row2.colb]

Tento index mohl udělat práci (v současnosti pouze gist indexy podporují omezení vyloučení):

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

Ale bohužel neexistuje žádná výchozí třída operátorů pro pole (která používá gist ). Existuje intarray modul , který poskytuje jeden pouze pro integer pole, ale nic pro text pole.

Pokud to opravdu chcete vyřešit, můžete vždy zneužít range typy (např. jsem použil sousední -|- operátor, který zpracovává všechny případy, které nelze zpracovat pomocí 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

... ale obávám se, že váš původní problém by mohl být vyřešen mnohem jednodušeji pomocí malého refaktorování databáze; což nás přivádí k otázce:jaký problém tímto chcete vyřešit?




  1. Vrátit názvy sloupců Oracle ve formátu table.column?

  2. Vyberte Součet ze dvou spojených tabulek

  3. Problémy s připojením MySQLdb

  4. Jak aktualizovat 3 sloupce tabulek, zatímco na stránce je viditelný pouze jeden sloupec