Sie müssen das Rad in PostgreSQL nicht neu erfinden, es gibt zwei implementierte einfache Methoden, um Überlappungsprüfungen zu erreichen:
- SQLs
OVERLAPS
Betreiber :
Ganz einfach,
where("(start_at, end_at) OVERLAPS (?, ?)", range.first, range.last)
Dies ermöglicht jedoch, dass ein Bereich genau nach dem anderen liegt
(mit anderen Worten, es prüft start <=time
Das ist normalerweise auch einfach. Aber PostgreSQL hat keinen eingebauten Bereichstyp für time
(allerdings gibt es tsrange
, tstzrange
und daterange
für die anderen zeitlichen Typen).
Sie müssen diesen Bereichstyp für sich selbst erstellen:
CREATE TYPE timerange AS RANGE (subtype = time);
Aber danach können Sie die Überlappung mit
überprüfenwhere("timerange(start_at, end_at) && timerange(?, ?)", range.first, range.last)
Vorteile von Bereichstypen:
-
Sie können selbst steuern, wie Sie mit Bereichsgrenzen umgehen möchten
z.B. Sie könnten
timerange(start_at, end_at, '[]')
verwenden um sowohl den Start- als auch den Endpunkt der Bereiche einzubeziehen. Standardmäßig schließt es den Anfang ein, schließt aber den Endpunkt der Bereiche aus. -
es kann indiziert werden, z.B. mit
CREATE INDEX events_times_idx ON events USING GIST (timerange(start_at, end_at));
-
Ausschlussbeschränkungen :Dies ist im Wesentlichen dasselbe, was Sie erreichen möchten, aber es wird auf DB-Ebene durchgesetzt (wie
UNIQUE
oder andere Einschränkungen):ALTER TABLE events ADD CONSTRAINT events_exclude_overlapping EXCLUDE USING GIST (timerange(start_at, end_at) WITH &&);