Cum să vă asigurați intrările cu intervale de timp care nu se suprapun?

voturi
1

Trebuie să mă asigur că baza mea de date conține doar intrări în care două sau mai multe dintre coloanele sale sunt unice. Acest lucru poate fi realizat cu ușurință cu UNIQUE constrângere peste acele coloane.

În cazul meu, trebuie să interzic duplicarea numai pentru suprapunerea intervalelor de timp. Masa are valid_from și valid_to coloane. În unele cazuri, ar trebui mai întâi să expire intrarea activă prin setare valid_to = now , apoi introduceți o nouă intrare ajustată la valid_from = now și valid_to = infinity .

Par să pot expira intrarea anterioară fără probleme de utilizare UPDATE , dar introducerea noii intrări pare a fi supărătoare, deoarece coloanele de bază sunt în prezent UNIQUE și, prin urmare, nu mai poate fi adăugat din nou.

M-am gândit să adaug valid_from și valid_to ca parte a UNIQUE constrângere, dar aceasta ar face ca restricția să fie mai liberă și să permită existența duplicatelor și a intervalelor de timp suprapuse.

Cum fac o constrângere pentru a garanta că duplicatele nu există cu suprapunerea valid_from și valid_totsrange ?

Par să caut EXCLUDE USING GIST , dar nu pare să susțină mai multe coloane? Acest lucru nu pare să funcționeze pentru mine:

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 &&);
Întrebat 10/05/2020 la 19:31
sursa de către utilizator
În alte limbi...                            


1 răspunsuri

voturi
0

Ai fost pe calea cea bună. Dar sintaxa restricțiilor de excludere este ușor diferită:

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 &&)
);

Este posibil să aveți nevoie să instalați modulul suplimentar btree_gist în primul rând, în funcție de definiția tabelului tău nedezvăluit.

Fiecare coloană trebuie să fie listată cu operatorul său.

Și aveți nevoie de un tip de gamă . presupunând timestamp with time zone pentru valid_from și valid_to , expresia tstzrange(valid_from, valid_to) ar face-o.

Legate de:


Poate , un design superior ar fi o relație între multe dintre dvs. registration intrări în tabel și 1-N într-o nouă registration_range masa. Și o anumită logică pentru a determina intrarea curentă valabilă (pentru orice moment dat). Depinde de mai multe informații nedivizate.

Publicat 13/05/2020 la 18:31
sursa de către utilizator

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