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

hlasů
1

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