V PostgreSQL nemusíte znovu objevovat kolo, existují dvě implementované jednoduché metody, jak dosáhnout kontroly překrývání:
- SQL
OVERLAPS
operátor :
Dost jednoduché,
where("(start_at, end_at) OVERLAPS (?, ?)", range.first, range.last)
To však umožňuje, aby jeden rozsah byl přesně za druhým
(jinými slovy, kontroluje počátek <=čas
I to je obvykle jednoduché. PostgreSQL však nemá vestavěný typ rozsahu pro time
(existují však tsrange
, tstzrange
a daterange
pro ostatní časové typy).
Tento typ rozsahu si musíte vytvořit sami:
CREATE TYPE timerange AS RANGE (subtype = time);
Poté však můžete zkontrolovat překrývání pomocí
where("timerange(start_at, end_at) && timerange(?, ?)", range.first, range.last)
Výhody typů rozsahů:
-
můžete se ovládat, jak chcete zacházet s hranicemi rozsahu
např. můžete použít
timerange(start_at, end_at, '[]')
zahrnout jak počáteční, tak koncový bod rozsahů. Ve výchozím nastavení zahrnuje začátek, ale nezahrnuje koncový bod rozsahů. -
lze jej indexovat, např. s
CREATE INDEX events_times_idx ON events USING GIST (timerange(start_at, end_at));
-
Omezení vyloučení :toto je v podstatě totéž, čeho chcete dosáhnout, ale bude to vynuceno na úrovni DB (např.
UNIQUE
nebo jakákoli jiná omezení):ALTER TABLE events ADD CONSTRAINT events_exclude_overlapping EXCLUDE USING GIST (timerange(start_at, end_at) WITH &&);