Bạn không cần phải phát minh lại bánh xe trong PostgreSQL, có hai phương pháp đơn giản được triển khai để đạt được kiểm tra chồng chéo:
Đủ đơn giản,
where("(start_at, end_at) OVERLAPS (?, ?)", range.first, range.last)
Tuy nhiên, điều này cho phép một phạm vi chính xác sau
phạm vi kia (nói cách khác, nó kiểm tra start <=time
Điều này cũng đơn giản, thông thường. Nhưng PostgreSQL không có loại phạm vi tích hợp cho time
(tuy nhiên có tsrange
, tstzrange
và daterange
cho các loại thời gian khác).
Bạn cần tạo loại phạm vi này cho chính mình:
CREATE TYPE timerange AS RANGE (subtype = time);
Nhưng sau đó, bạn có thể kiểm tra chồng chéo với
where("timerange(start_at, end_at) && timerange(?, ?)", range.first, range.last)
Ưu điểm của các loại phạm vi:
-
bạn có thể kiểm soát bản thân, bạn muốn xử lý các ranh giới phạm vi như thế nào
f.ex. bạn có thể sử dụng
timerange(start_at, end_at, '[]')
để bao gồm cả điểm đầu và điểm cuối của phạm vi. Theo mặc định, nó bao gồm điểm bắt đầu, nhưng không bao gồm điểm cuối của phạm vi. -
nó có thể được lập chỉ mục, f.ex. với
CREATE INDEX events_times_idx ON events USING GIST (timerange(start_at, end_at));
-
Ràng buộc loại trừ :điều này về cơ bản giống nhau, những gì bạn muốn đạt được, nhưng nó sẽ được thực thi ở cấp DB (như,
UNIQUE
hoặc bất kỳ ràng buộc nào khác):ALTER TABLE events ADD CONSTRAINT events_exclude_overlapping EXCLUDE USING GIST (timerange(start_at, end_at) WITH &&);