多表外键

Meg*_*Hit 5 mysql foreign-key database-design

我有以下 3 个表:

???????????????????
?   Companies     ?
???????????????????
? id              ?
? name            ?
? type            ?
? etc...          ?
???????????????????
????????????????
?   Contacts   ?
????????????????
? id           ?
? company_id   ?
? first_name   ?
? last_name    ?
? etc...       ?
????????????????
?????????????????
?   Addresses   ?
?????????????????
? id            ?
? foreign_key   ?
? address_1     ?
? address_2     ?
? city          ?
? state         ?
? zip           ?
? etc...        ?
?????????????????
Run Code Online (Sandbox Code Playgroud)

我的问题是公司和联系人都可以有多个关联的地址。他们的 ID 号可能重叠。我将在表的foreign_key列中存储什么addresses

a1e*_*x07 4

你有几个选择。我会描述我最喜欢的一个,但是您可以找到其他人搜索“解决数据库中的多态关联”。为companiesand添加一个公用表contacts(我更愿意重命名contactspeopleor persons),例如party。因此,companiescontacts将有 FK 到partyparty_address(address_id,party_id)然后分别将带有 FK 的链接表添加到addressesparty

更新 例如(我知道它过于简单化,通常你可能有不同的地址类型、地址更改历史记录等,但我想它说明了想法)。

注意:使用enum是因为mysql仍然没有检查约束。添加了对 (party_id, party_type) 的唯一约束,以便子表可以具有对其的外键引用;因此,在数据库级别实施和执行的可选关系——当事人可以是个人或组织;不可能同时是个人和组织。

  CREATE TABLE PARTY (party_id int not null auto_increment primary key,
party_type enum('person','organization') not null,
CONSTRAINT UQ_PARTY UNIQUE(party_id,party_type));

CREATE TABLE PERSON (party_id int not null primary key, 
party_type enum('person') NOT NULL DEFAULT 'person',
....
CONSTRAINT FK_PERSON_PARTY FOREIGN KEY(party_id,party_type) 
 REFERENCES PARTY(party_id,party_type));

CREATE TABLE ORGANIZATION (party_id int not null primary key, 
party_type enum('organization') NOT NULL DEFAULT 'organization',
....
CONSTRAINT FK_PERSON_PARTY FOREIGN KEY(party_id,party_type) 
 REFERENCES PARTY(party_id,party_type));

CREATE TABLE ADDRESS(address_id INT NOT NULL auto_increment PRIMARY KEY,
.... );

CREATE TABLE PARTY_ADDRESS (party_id INT NOT NULL, address_id INT NOT NULL,
CONSTRAINT PK_PARTY_ADDRESS PRIMARY KEY(party_id,address_id),
CONSTRAINT FK_PARTY_ADDRESS_PARTY FOREIGN KEY (party_id) REFERENCES PARTY(party_id),
CONSTRAINT FK_PARTY_ADDRESS_ADDRESS FOREIGN KEY (address_id) REFERENCES ADDRESS(address_id));
Run Code Online (Sandbox Code Playgroud)

  • 你在这里有一个很好的答案的条件。由于他们似乎对关系数据没有概念性的理解,您是否愿意为OP编写更多的脚本/图表(使用示例结构)? (2认同)