Hvordan sikre påmeldinger med ikke-overlappende tidsintervaller?

stemmer
1

Jeg må sørge for at databasen min bare inneholder oppføringer der to eller flere av kolonnene er unike. Dette kan lett oppnås med a UNIQUE begrensning over disse kolonnene.

I mitt tilfelle trenger jeg å forby duplisering bare for overlappende tidsintervaller. Tabellen har valid_from og valid_to kolonner. I noen tilfeller kan det hende at du først må utløpe den aktive oppføringen til ved å stille inn valid_to = now , og deretter sette inn en ny oppføring justert til valid_from = now og valid_to = infinity .

Jeg ser ut til å kunne utløpe den forrige oppføringen uten problemer med å bruke UPDATE , men det er vanskelig å sette inn den nye oppføringen siden basekolonnene mine for øyeblikket er UNIQUE , og kan derfor ikke legges til igjen.

Jeg tenkte å legge til valid_from og valid_to som en del av UNIQUE begrensning, men det ville bare gjøre begrensningen løsere, og la duplikater og overlappende tidsintervaller å eksistere.

Hvordan setter jeg en begrensning for å sikre at duplikater ikke eksisterer med overlapping valid_from og valid_totsrange ?

Jeg ser ut til å være ute etter EXCLUDE USING GIST , men det ser ikke ut til å støtte flere kolonner? Dette ser ikke ut til å fungere for meg:

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 &&);
Publisert på 10/05/2020 klokken 19:31
kilden bruker
På andre språk...                            


1 svar

stemmer
0

Du var på rett vei. Men syntaks for begrensninger for eksklusjon er litt annerledes:

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

Du må kanskje installere tilleggsmodulen btree_gist først, avhengig av din ikke-avslørte tabeldefinisjon.

Hver kolonne må være oppført med sin respektive operatør.

Og du trenger en rekkevidde . Forutsatt timestamp with time zone til valid_from og valid_to , uttrykket tstzrange(valid_from, valid_to) ville gjøre det.

I slekt:


Kanskje ville en overlegen design være en-til-mange-forhold mellom deg registration tabell og 1-N oppføringer i en ny registration_range bord. Og litt logikk for å bestemme den gjeldende gyldige oppføringen (for et gitt tidspunkt). Avhenger av mer ikke avslørt informasjon.

Svarte 13/05/2020 kl. 18:31
kilden bruker

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