Jak zajistit vstupy s nepřekrývajícími se časovými intervaly?

hlasů
50

Musím zajistit, aby moje databáze obsahovala pouze záznamy, kde jsou dva nebo více jejích sloupců jedinečné. Toho lze snadno dosáhnout pomocí UNIQUE omezení nad těmito sloupci.

V mém případě musím zakázat duplicitu pouze pro překrývající se časová období. Tabulka má valid_from a valid_to sloupce. V některých případech může být nejprve nutné platnost aktivního záznamu vyřadit nastavením valid_to = now a poté vložte nový záznam upravený na valid_from = now a valid_to = infinity .

Zdá se, že jsem schopen vypršet předchozí vstup bez jakýchkoli problémů s používáním UPDATE , ale vložení nové položky se zdá být problematické, protože mé základní sloupce jsou v současné době UNIQUE , a proto jej nelze znovu přidat.

Pomyslel jsem na přidání valid_from a valid_to jako součást UNIQUE omezení, ale to by pouze uvolnilo omezení a umožnilo existenci duplikátů a překrývajících se časových období.

Jak mohu udělat omezení, aby se zajistilo, že duplikáty neexistují s překrýváním valid_from a valid_totsrange ?

Zdá se, že hledám EXCLUDE USING GIST , ale zdá se, že nepodporuje více sloupců? Nezdá se mi, že by to fungovalo:

ALTER TABLE registration 
DROP Constraint IF EXISTS registration_{string.Join('_', listOfAttributes)}_key, 
ADD Constraint registration_{string.Join('_', listOfAttributes)}_key EXCLUDE USING GIST({string.Join(',', listOfAttributes)} WITH =, valid WITH &&);
Položena 10/05/2020 v 19:31
zdroj uživatelem
V jiných jazycích...                            


1 odpovědí

hlasů
0

Byli jste na správné cestě. Syntaxe omezení vyloučení se však mírně liší:

CREATE TABLE registration  (
  tbl_id  integer PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY
, col_a   integer NOT NULL
, col_b   integer NOT NULL
, valid_from timestamptz
, valid_to   timestamptz
, CONSTRAINT no_overlap
    EXCLUDE USING gist (col_a with =, col_b with =, tstzrange(valid_from, valid_to) WITH &&)
);

Možná budete muset nainstalovat další modul btree_gist nejprve, v závislosti na vaší nezveřejněné definici tabulky.

Každý sloupec musí být uveden u příslušného operátora.

A potřebujete typ rozsahu . Za předpokladu timestamp with time zone pro valid_from a valid_to , výraz tstzrange(valid_from, valid_to) udělal by to.

Příbuzný:


Možná by nadřazený design byl vztahem mezi vámi registration tabulky a položky 1-N v novém registration_range stůl. A určitá logika pro určení aktuálně platné položky (pro jakýkoli daný časový okamžik). Závisí na více nezveřejněných informacích.

Odpovězeno 13/05/2020 v 18:31
zdroj uživatelem

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more