уникальный индекс postgresql, предотвращающий перекрытие - PullRequest
0 голосов
/ 07 ноября 2018

Моя таблица разрешений выглядит так:

id serial,
person_id integer,
permission_id integer,
valid_from date,
valid_to date

Я бы хотел запретить создание разрешений, которые перекрывают valid_from, valid_to date

например.

1 | 1 | 1 | 2010-10-01 | 2999-12-31
2 | 1 | 2 | 2010-10-01 | 2020-12-31
3 | 2 | 1 | 2015-10-01 | 2999-12-31

это можно добавить:

4 | 1 | 3 | 2011-10-01 | 2999-12-31 - because no such permission
5 | 2 | 1 | 2011-10-10 | 2999-12-31 - because no such person
6 | 1 | 2 | 2021-01-01 | 2999-12-31 - because doesn't overlaps id:2

но это не может

7 | 1 | 1 | 2009-10-01 | 2010-02-01 - because overlaps id:1
8 | 1 | 2 | 2019-01-01 | 2022-12-31 - because overlaps id:2
9 | 2 | 1 | 2010-01-01 | 2016-12-31 - beacuse overlaps id:3

Я могу сделать внешнюю проверку, но задаюсь вопросом, возможно ли это сделать в базе данных

1 Ответ

0 голосов
/ 07 ноября 2018

Уникальное ограничение основано на операторе равенства и не может использоваться в этом случае, но вы можете использовать исключающее ограничение. Ограничение использует операторы btree <> и =, следовательно, у вас есть установить расширение btree_gist.

create extension if not exists btree_gist;

create table permission(
    id serial,
    person_id integer,
    permission_id integer,
    valid_from date,
    valid_to date,
    exclude using gist (
        person_id with =, 
        permission_id with =, 
        daterange(valid_from, valid_to) with &&)
);

Эти вставки успешны:

insert into permission values
    (1, 1, 1, '2010-10-01', '2999-12-31'),
    (2, 1, 2, '2010-10-01', '2020-12-31'),
    (3, 2, 1, '2015-10-01', '2999-12-31'),
    (4, 1, 3, '2011-10-01', '2999-12-31'),
    (5, 3, 1, '2011-10-10', '2999-12-31'), -- you meant person_id = 3 I suppose
    (6, 1, 2, '2021-01-01', '2999-12-31'),
    (7, 1, 1, '2009-10-01', '2010-02-01'); -- ranges do not overlap!

но это не так:

insert into permission values
    (8, 1, 2, '2019-01-01', '2022-12-31');

ERROR:  conflicting key value violates exclusion constraint "permission_person_id_permission_id_daterange_excl"
DETAIL:  Key (person_id, permission_id, daterange(valid_from, valid_to))=(1, 2, [2019-01-01,2022-12-31)) conflicts with existing key (person_id, permission_id, daterange(valid_from, valid_to))=(1, 2, [2010-10-01,2020-12-31)).

Попробуйте в rextester.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...