PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

Empêcher les entrées adjacentes/qui se chevauchent avec EXCLUDE dans PostgreSQL

Les types de plage se composent d'une bordure inférieure et d'une bordure supérieure, qui peuvent être incluses ou exclues. Le cas d'utilisation typique (et par défaut pour les types de plage) consiste à inclure le plus bas et exclure la borne supérieure.

Hors chevauchement gammes semble clair. Il y a un bel exemple de code dans le manuel

De plus, créez une autre contrainte d'exclusion en utilisant l'opérateur adjacent -|- pour exclure également adjacent entrées. Les deux doivent être basés sur GiST les index car GIN n'est actuellement pas pris en charge pour cela.

Pour le garder propre, j'appliquerais [) limites (incluant inférieure et excluant supérieure) pour toutes les entrées avec un CHECK contrainte utilisant les fonctions de plage :

CREATE TABLE tbl (
   tbl_id serial PRIMARY KEY
 , tsr tsrange
 , CONSTRAINT tsr_no_overlap  EXCLUDE USING gist (tsr WITH &&)
 , CONSTRAINT tsr_no_adjacent EXCLUDE USING gist (tsr WITH -|-)
 , CONSTRAINT tsr_enforce_bounds CHECK (lower_inc(tsr) AND NOT upper_inc(tsr))
);

db<>jouez ici
(Vieux violon SQL)

Malheureusement, cela en crée deux des index GiST identiques pour implémenter les deux contraintes d'exclusion, là où une seule suffirait, logiquement. Cela semble être une lacune de l'implémentation actuelle (jusqu'à au moins Postgres 11).