2012-11-01 35 views
-1

我想創建一個包含人,房子和家庭,其中只有來自同一家庭的人被允許住在同一所房子錶行只可插入。SQL表其中,如果唯一的列

我至今不能正常工作,因爲我只能發佈一個行與獨特的家庭和房子。有沒有辦法做到這一點?正確的表的

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' 
+1

有你存儲在VARCHAR(64)字段的數字,還是我失去了一些東西什麼特別的原因? – Bridge

+0

他們是爲了是字符串,我只是忘了加上「 –

+0

做家庭和房屋的價值有實際是相等的,或者是僅僅的情況下,對於屬於某個房子,他們都必須具備的所有行相同的家庭標識符(不管可能是什麼)?換句話說,是'男人','3','1';女人,'3','1'是一組有效的行,因爲家中的每個人'1'都在家庭'3'中? –

回答

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

這樣我可以有多個居民在同一個家庭,但只有一個家庭到家。

+0

我可能已經有點不清楚。房子只能容納一個家庭,但一個家庭可以有幾套房子。 –

+0

這個設計也符合這個條件。 – titanofold

+0

你說得對,我誤解了表。謝謝! –

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". 
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

相關問題