Sql表,如果唯一列,则只能插入行

时间:2012-11-01 16:02:20

标签: sql postgresql database-design unique

我想创建一个包含人,房子和家庭的桌子,只允许来自同一家庭的人住在同一栋房子里。

到目前为止我所做的不起作用,因为我只能发布一行有独特的家庭和房子。有没有办法做到这一点?

CREATE TABLE familyhouse (
  person VARCHAR(64),
  house VARCHAR(64),
  family VARCHAR(64),
  unique(house,family)
);

正确的表格示例:

man,'1','1'
man2,'1','1'
man3,'1','1'
man4,'2','2'
man5,'2','2'
man6,'3','3'

不正确的表格示例:

man,'1','1'
man2,'1','1'
man3,'1','2'

3 个答案:

答案 0 :(得分:2)

我会利用外键的力量,把房子和家人放在他们自己的桌子上(family_house),并为居民提供一张单独的桌子。

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
);

这样我可以在同一个家中有多个居民,但只有一个家庭到家。

答案 1 :(得分:1)

您可以使用CHECK CONSTRAINT来维护:

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));

如上所述,下面的第二个插入将失败:

INSERT INTO familyhouse VALUES(1, 1, 1);
INSERT INTO FamilyHouse VALUES(2, 2, 1);

带有消息:

ERROR: new row for relation "familyhouse" violates check constraint "chk_familyhouse": INSERT INTO FamilyHouse VALUES(2, 2, 1)

<强> SQL Fiddle Example

答案 2 :(得分:0)

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

现在,如果您尝试将family_id 2中的某个人插入同一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".