I want to create a table which contains person, house and family, where only persons from the same family are allowed to live in the same house.
What I have so far does not work because I can only post one row with unique family and house. Is there any way to do this?
CREATE TABLE familyhouse (
person VARCHAR(64),
house VARCHAR(64),
family VARCHAR(64),
unique(house,family)
);
Example of correct table:
man,'1','1'
man2,'1','1'
man3,'1','1'
man4,'2','2'
man5,'2','2'
man6,'3','3'
Example of non-correct table:
man,'1','1'
man2,'1','1'
man3,'1','2'
I'd leverage the power of foreign keys and put the house and family in their own table (family_house) and a separate table for the residents.
CREATE TABLE family_house (
house VARCHAR(128) NOT NULL UNIQUE,
family VARCHAR(64) NOT NULL,
PRIMARY KEY (house, family)
);
CREATE TABLE residents (
person VARCHAR(64),
house VARCHAR(128),
family VARCHAR(64),
UNIQUE (person, house, family),
FOREIGN KEY (house, family) REFERENCES family_house
);
This way I can have multiple residents in the same home, but only one family to a home.
You can use a CHECK CONSTRAINT to maintain this:
CREATE TABLE familyhouse (
person VARCHAR(64),
house VARCHAR(64),
family VARCHAR(64)
);
CREATE FUNCTION CheckFamilyHouse(VARCHAR(64), VARCHAR(64))
RETURNS BOOLEAN AS $$
SELECT CASE WHEN EXISTS
( SELECT 1
FROM FamilyHouse
WHERE Family = $1
AND House != $2
)
THEN false
ELSE true
END
$$ LANGUAGE SQL;
ALTER TABLE familyHouse
ADD CONSTRAINT CHK_FamilyHouse
CHECK(CheckFamilyHouse(family, house));
With the above in place the second insert below will fail:
INSERT INTO familyhouse VALUES(1, 1, 1);
INSERT INTO FamilyHouse VALUES(2, 2, 1);
with the message:
ERROR: new row for relation "familyhouse" violates check constraint "chk_familyhouse": INSERT INTO FamilyHouse VALUES(2, 2, 1)
create table house (
id serial primary key
);
create table family (
id serial primary key
);
create table house_family (
house_id integer,
family_id integer,
primary key (house_id, family_id),
foreign key (house_id) references house (id),
foreign key (family_id) references family (id)
);
create table person (
id serial primary key,
family_id integer,
house_id integer,
foreign key (house_id, family_id) references house_family (house_id, family_id)
);
insert into house values (1),(2),(3);
insert into family values (1),(2),(3);
insert into house_family values (1,1),(2,2),(3,3);
insert into person (family_id, house_id) values (1,1),(1,1);
select * from house;
id
----
1
2
3
select * from family;
id
----
1
2
3
select * from house_family;
house_id | family_id
----------+-----------
1 | 1
2 | 2
3 | 3
select * from person;
id | family_id | house_id
----+-----------+----------
5 | 1 | 1
6 | 1 | 1
Now if you try to insert a person from family_id 2 in the same house_of family_id 1:
insert into person (family_id, house_id) values (2,1);
ERROR: insert or update on table "person" violates foreign key constraint "person_house_id_fkey"
DETAIL: Key (house_id, family_id)=(1, 2) is not present in table "house_family".
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.