PostgreSQLで車輪の再発明をする必要はありません。オーバーラップチェックを実現するために、2つの簡単な方法が実装されています。
- SQLの
OVERLAPS
オペレーター :
簡単です
where("(start_at, end_at) OVERLAPS (?, ?)", range.first, range.last)
ただし、これにより、1つの範囲を正確に次の範囲にすることができます
(つまり、開始<=時間<終了をチェックします。 。
通常、これも簡単です。ただし、PostgreSQLにはtime
の範囲タイプが組み込まれていません。 (ただし、tsrange
があります 、tstzrange
、およびdaterange
他の時間タイプの場合)。
この範囲タイプを自分で作成する必要があります:
CREATE TYPE timerange AS RANGE (subtype = time);
ただし、この後、重複を確認できます
where("timerange(start_at, end_at) && timerange(?, ?)", range.first, range.last)
範囲タイプの長所:
-
自分で制御できます。範囲の境界をどのように処理しますか
f.ex.
timerange(start_at, end_at, '[]')
を使用できます 範囲の開始点と終了点の両方を含めます。デフォルトでは、開始点は含まれますが、範囲の終了点は除外されます。 -
インデックスを付けることができます、f.ex。と
CREATE INDEX events_times_idx ON events USING GIST (timerange(start_at, end_at));
-
除外の制約 :これは基本的に同じであり、達成したいことですが、DBレベルで適用されます(
UNIQUE
など)。 またはその他の制約):ALTER TABLE events ADD CONSTRAINT events_exclude_overlapping EXCLUDE USING GIST (timerange(start_at, end_at) WITH &&);