正确使用SQL中的表之间的多对多关系?

时间:2013-01-05 19:15:07

标签: mysql sql database foreign-keys

我有一个任务(所以相应地回答),其中包括动物和动物园管理员之间的多对多关系,我设置了我的SQL来创建这种关系,如下所示:

CREATE TABLE Animal
( 
    animalID VARCHAR(5) NOT NULL PRIMARY KEY,
    -- more rows created here;
);

CREATE TABLE Zookeeper 
( 
    employeeID VARCHAR(5) NOT NULL PRIMARY KEY,
    -- more rows created here;
);

CREATE TABLE Animal_Zookeeper
(
    animal_id VARCHAR(5) NOT NULL,
    employee_id VARCHAR(5) NOT NULL,
    PRIMARY KEY (employee_id, animal_id)
);

-- insert data to Animal/Zookeeper tables

ALTER TABLE Animal_Zookeeper
    ADD CONSTRAINT FK_Animal_Zookeper_Relation_1
    FOREIGN KEY (animal_id)
    REFERENCES Animal(animalID)
    ON UPDATE RESTRICT
    ON DELETE RESTRICT,
    ADD CONSTRAINT FK_Animal_Zookeeper_Relation_2
    FOREIGN KEY (employee_id)
    REFERENCES Zookeeper(employeeID)
    ON UPDATE RESTRICT
    ON DELETE RESTRICT;

我想检查这是否是表达这种关系的正确方法,或者我是否遗漏了一些东西,因为我对这种行为的表现并不完全有信心(一些澄清会很好:D )。我也有一个零或更多的一个或多个关系来表示,是否就像上面那样简单地完成了?

在此先感谢,因为我说这是为了一项任务,所以不要为我做,只需要一些检查,一些指针会有所帮助:p

1 个答案:

答案 0 :(得分:3)

这是一个适当的多对多设置。对于0/1对多,您只需删除animal_zookeeper表,并将关系移动到父动物和/或动物园管理员表中的一个,例如:

table animal {
  ...
  zookeeper foreign key ...
}

这样可以将 ONE 动物园管理员分配给动物,但同一个动物园管理员可以分配多只动物。如果您需要动物拥有动物园管理员,则zookeeper字段为“非空”。如果你想让没有zookeeper的“孤儿”动物,你可以在zookeeper字段中允许空值。


编辑:设定理论

将两个表视为一组记录:一组动物园管理员和一组动物。

这是一个1:很多的设置,动物很多,动物园管理员就是那个。请注意,“一”并不意味着只有一个动物园管理员。 x:y stuff表示表中的 RECORDS 。一个动物园管理员记录可以有许多动物记录指向它。这并不意味着你有一个动物园管理员照顾整个动物园。

 table animals {
     id
     zookeeper foreign key (zookeepers.id) default null
 }

 table zookeepers {
     id
 }

如果您有动物园管理员“John”和“Jane”,那么任何给定的动物都可以(或者都没有)分配给它们。

 (many)    (one/none)
 tiger     John
 leopard   John
 monkey    (null)    <--monkey is orphaned, with no zookeeper assigned.
 elephant  Jane

所以John正在照顾老虎和豹子(一个动物园管理员,很多动物),Jane有大象(一个:很多偶然发生在1:1),猴子本身就是没有人。但是你永远不会得到John: monkey + Jane: monkey,因为动物只能分配一个动物园管理员。

要强制执行一个:很多,意味着没有孤儿,你会改变你的动物:

table animal {
   id
   zookeeper foreign key (zookeepers.id) NOT NULL
                                        ^^^^^^^^^
}

现在猴子不能“没有人”,因为数据库强制你将动物园管理员分配给猴子。它仍然是1:m,但你现在不允许0:m的情况。

1:m“确实存在一个可以分配多个Y的X”。例如一个动物园管理员可以处理多个动物,但每只动物只能分配一个动物园管理员。反之亦然 - 一只动物可以有多个饲养员,但每只饲养者只能有一只动物

m:m:大开,多种动物与多个动物园饲养员有不同的组合。这是最灵活的设置,允许任何zookeeper:动物关系的组合。但它的副作用是很难防止0:m的情况,而不在zookeeper_animal表上添加CHECK CONSTRAINTS,而不是所有数据库都支持(例如mysql)。