表格与多个表格有一对一的关系

4

1) 一张表可以与多张表建立一对一的关系吗?

更明确地说,如果我想插入数据,第一个表将受到影响,但只有其中一张其他表会受到影响。

2) 如果可以,那么主键将是什么?

3) 另外,如果我想从这些表中检索多条记录,查询将是什么样子?

谢谢。

2个回答

7
一张表是否可以与多张表建立一对一关系?可以,但是前提是你指的是1:0/1:。
Create Table Parent
    (
    Id ... not null Primary Key
    , ...
    )

Create Table Child1
    (
    Id ... not null Primary Key
    , Foreign Key ( Id ) References Parent ( Id )
    ...
    )

Create Table Child2
    (
    Id ... not null Primary Key
    , Foreign Key ( Id ) References Parent ( Id )
    ...
    )

这种设置需要先在父表中输入一个值,然后按照任意顺序在子表中添加值。此外,您可以向其中一个子表添加值而不是另一个子表,因为它们都只依赖于父表中的值的存在,而不是彼此之间。


补充说明

要从子表中进行选择,需要像其他父子关系一样进行相同的过程。例如:

Select P.Col1, P.Col2...
    , Child1.Col1, Child1.Col2...
From Parent
    Inner Join Child1
        On Child1.FKCol = Parent.PKCol

在这里使用内连接,我只返回存在子行的父行。如果您想要所有父行和仅匹配的那些子行,则应该使用左连接而不是内连接。如果您想同时从多个子表中选择数据,只需将它们包含在From子句中即可:

Select P.Col1, P.Col2...
    , Child1.Col1, Child1.Col2...
    , Child2.Col1, Child2.Col2...
    , Child3.Col1, Child3.Col2...
From Parent
    Left Join Child1
        On Child1.FKCol = Parent.PKCol
    Left Join Child2
        On Child2.FKCol = Parent.PKCol
    Left Join Child3
        On Child2.FKCol = Parent.PKCol

没错。但是我的问题是,插入将会是:1)在父级中插入。2)从父级选择ID(自动生成)。3)在其中一个子级中插入。这样正确吗? - Roobah
@HTB - 如果您使用AutoNumber或Identity值作为主键,则是正确的。 - Thomas
好的。那么从不同的子表中检索一些记录怎么办?我需要使用连接吗,还是像这样操作:"select * from parent, child1, child2.. where parent.id = child1.id || parent.id = child2.id.." !? - Roobah
@HTB - 我已经扩展了我的答案,向您展示了从子表中检索数据的示例。 - Thomas

1
在SQL Server中,您肯定可以设计一个能够表示这种关系的数据库。您可以通过将子表使用ParentId作为其主键并强制唯一性来强制执行一对一关系。
如果您想查询一个父表及其可能存在或不存在现有记录的三个子表,则查询语句可能如下所示:
SELECT * FROM ParentTable as pt
LEFT JOIN ChildTable1 as ct1
ON pt.id = ct1.ParentId
LEFT JOIN ChildTable2 as ct2
ON pt.id = ct2.ParentId
LEFT JOIN ChildTable3 as ct3
ON pt.ID = ct3.ParentId

我的问题是,为什么要将一对一的关系分成多个表?如果将所有数据都保存在一个表中,您也可以强制执行一对一的关系。这样做会使查询更清晰(没有联接)且性能更好。


不错。我的父表是Place,而子表是Restaurant和Hotel。 子表在父表中具有共享列(例如名称和电话)。每个子表都有特殊列,例如Restaurant的dish和Hotel的stars。所以,我必须对其进行拆分。如果您有更好的方法,请建议。 - Roobah
1
啊,我明白了。你正在处理数据库中的模型继承问题。我建议看一下这篇SO帖子:https://dev59.com/NXVC5IYBdhLWcg3wxEJ1。它介绍了一些不同的技术来解决这个问题。 - Abe Miessler
哦,非常感谢Abe。链接帮了我很多忙。很棒的概念。谢谢。 - Roobah

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接