U hoeft het wiel niet opnieuw uit te vinden in PostgreSQL, er zijn twee eenvoudige methoden geïmplementeerd om overlapcontroles te realiseren:
- SQL's
OVERLAPS
operator :
Simpel genoeg,
where("(start_at, end_at) OVERLAPS (?, ?)", range.first, range.last)
Dit zorgt er echter voor dat het ene bereik precies na het andere komt
(met andere woorden, het controleert start <=time
Dit is meestal ook eenvoudig. Maar PostgreSQL heeft geen ingebouwd bereiktype voor time
(er zijn echter tsrange
, tstzrange
, en daterange
voor de andere tijdelijke typen).
U moet dit bereiktype voor uzelf maken:
CREATE TYPE timerange AS RANGE (subtype = time);
Maar hierna kunt u overlapping controleren met
where("timerange(start_at, end_at) && timerange(?, ?)", range.first, range.last)
Voordelen van bereiktypes:
-
je kunt jezelf beheersen, hoe wil je omgaan met bereikgrenzen
bijv. je zou kunnen gebruiken
timerange(start_at, end_at, '[]')
om zowel het begin- als het eindpunt van de bereiken op te nemen. Standaard bevat het het begin, maar niet het eindpunt van de bereiken. -
het kan worden geïndexeerd, bijv. met
CREATE INDEX events_times_idx ON events USING GIST (timerange(start_at, end_at));
-
Uitsluitingsbeperkingen :dit is in wezen hetzelfde, wat u wilt bereiken, maar het wordt afgedwongen op DB-niveau (zoals,
UNIQUE
of andere beperkingen):ALTER TABLE events ADD CONSTRAINT events_exclude_overlapping EXCLUDE USING GIST (timerange(start_at, end_at) WITH &&);