I have a schema like this one:
create table users (
id bigint primary key generated always as identity,
name text not null
);
create table feature (
id bigint primary key generated always as identity,
value text not null check (value != '')
);
create unique index ux1 on feature(value);
-- link table
create table user_feature (
id bigint generated always as identity,
user_id bigint not null references users(id),
feature_id bigint not null references feature(id)
);
create unique index ux2 on user_feature(user_id, feature_id);
-- feature values
insert into feature (value) values ('A'), ('B'), ('C'), ('D');
So an user can have 0 or more features, he can have just one type of same feature but I would like add some logic/conditions between the features that an user can have.
For example let’s say feature B
and C
are incompatibles, so user can have none of them, B
or C
but not both, not B
and C
together.
What is, if there is, a proper way to do this ?
I was reading and if am not wrong the only option is a trigger right (on insert / update)?
I am not used to triggers, if someone can at least gives an example.
I am using version 14.
Thanks for the help.
2
Answers
Yes you definitely need to enforce such behavior with triggers. Here is some example code for checking that a user cannot have feature B and C:
Behaviour:
When updating a user with this data:
I would avoid triggers. If two users insert values B and C in separate transactions, your trigger won’t catch it since each session will see only the value it inserted.
You can use a unique index with a case expression instead:
This unique index
CASE
expressionHowever, this approach is somewhat limited:
SQL Fiddle