简体   繁体   English

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

[英]Proper usage of a many-to-many relationship between tables in SQL?

I have an assignment (so answer accordingly) which includes a many-to-many relationship between Animals and Zookeepers and I've set my SQL to create this relationship as the following: 我有一个作业(因此要作相应的回答),其中包括动物与动物园管理员之间的多对多关系,并且我将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;

I'd like to check if this is the correct way to represent this relationship, or if I've missed something out as I'm not completely confident in how this is meant to behave (some clarification would be nice :D). 我想检查这是否是表示这种关系的正确方法,或者我是否错过了某些内容,因为我对行为的方式并不完全自信(有些澄清会很不错:D)。 I also have a Zero or More to One or More relationship to represent, is that simply done the same way as above? 我也有一个零个或多个与一个或多个关系来表示,这是否与上述相同?

Thanks in advance, as I said it's for an assignment so don't do it for me, just a bit of checking and some pointers would be helpful :p 在此先感谢您,正如我所说的,这是分配任务,所以不要为我做,只需要进行一些检查,便可以使用一些指针:p

That's a proper many-to-many setup. 这是正确的多对多设置。 For 0/1-to-many, you'd simply eliminate the animal_zookeeper table, and move the relationship into one of the parent animal and/or zookeeper tables, eg: 对于一对多的0/1,您只需消除animal_zookeeper表,然后将关系移动到父动物和/或zookeeper表之一,例如:

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

this would allow ONE zookeeper to be assigned to an animal, but the same zookeeper could have multiple animals assigned to them. 这将允许将一个动物园管理员分配给一只动物,但是同一动物园管理员可以将多个动物指派给它们。 If you require an animal to have a zookeeper, the zookeeper field is "not null". 如果您要求动物拥有动物园管理员,则动物园管理员字段为“ not null”。 If you want to have "orphaned" animals with no zookeeper, you allow nulls in the zookeeper field. 如果要让没有动物园管理员的“孤立的”动物,请在“动物园管理员”字段中允许为空。


edit: set theory 编辑:集合论

view your two tables as sets of records: a set of zookeepers, and a set of animals. 以记录集的形式查看您的两个表:一组动物园管理员和一组动物。

This is the setup for a 1:many, where the animals are the many, and the zookeepers are the one. 这是1:1的设置,其中动物很多,动物园管理员就是其中之一。 Note that the "one" doesn't mean there's only one zookeeper. 请注意,“一个”并不意味着只有一个动物园管理员。 The x:y stuff refers to RECORDS in the tables. x:y表示表中的RECORDS one zookeeper record can have many animal records pointing at it. 一个动物园管理员记录可以有许多动物记录指向该记录。 it doesn't mean you've got one zookeeper taking care of the entire zoo. 这并不意味着您有一个动物园管理员来照顾整个动物园。

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

 table zookeepers {
     id
 }

If you've got zookeepers "John" and "Jane", then any given animal can have either (or neither) assigned to them. 如果您有动物园管理员“约翰”和“简”,那么任何给定的动物都可以分配一个(或两个都不分配)。

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

So John is taking care of the tiger and leopard (one zookeeper, many animals), Jane has the elephant (a one:many that happens by chance to be a 1:1), and the monkey is all by itself with no one. 因此,约翰(John)照顾着老虎和豹(一只动物园管理员,许多动物),简(Jane)拥有大象(一只:许多偶然以1:1的比例发生),而猴子本身就是一个人。 But you'd never get John: monkey + Jane: monkey , because the animals can only ever have ONE zookeeper assigned to them. 但是您永远不会得到John: monkey + Jane: monkey ,因为动物只能分配一个动物园管理员。

To enforce a one:many, meaning no orphaned animals, you'd change your animal to be: 要实施一个:很多(意味着没有孤儿),您可以将动物更改为:

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

now the monkey cannot have "no one", because the database enforces that you assign a zookeeper to the monkey. 现在,猴子不能再没有人了,因为数据库会强制您将动物园管理员分配给猴子。 It's still a 1:m, but you've now dissallowed the 0:m case. 仍然是1:m,但是您现在不使用0:m了。

1:m "there exists exactly ONE X which can have mutiple Y assigned to it". 1:m:“确切存在一个可以分配多个Y的X”。 eg one zookeeper can handle multiple animals, but each animal can have only one zookeeper assigned to them. 例如,一个动物园管理员可以处理多只动物,但是每只动物只能指派一个动物园管理员。 or vice versa - one animal can have multiple keepers, but each keeper can only have one animal 反之亦然-一只动物可以有多个饲养员,但每只饲养员只能饲养一只动物

m:m: wide open, multiple animals associated in varying combinations with multiple zookeepers. m:m:敞开,多种动物与多种动物园饲养者有不同的组合。 This is the most flexible setup, allowing any combination of zookeeper:animal relationships. 这是最灵活的设置,允许任何Zookeeper:动物关系的组合。 But its side effect is that it's difficult to prevent a 0:m situation, without adding CHECK CONSTRAINTS on the zookeeper_animal table, which not all databases support (eg mysql). 但是它的副作用是,如果不在zookeeper_animal表上添加CHECK CONSTRAINTS(不是所有数据库都支持的表),则很难防止0:m情况。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM