如何处理 SQL 服务器中的多值外键

How to deal with multi-valued foreign key in SQL Server

我在 SQL 服务器中有一个 table AuthorsAuthor_ID 作为主键。

Authorstable结构

Author_ID | Author_Name  
----------------------------
677       | Nuno Vasconcelos
1359      | Peng Shi
6242      | Z. Q. Shi  
...       | ...  
...       | ...   

我有另一个 table CoAuthors,其中 CoAuthor_ID 作为主键,Author_ID 作为外键。

CoAuthorstable结构

CoAuthor_ID | CoAuthor_Name | Author_ID  
---------------------------------------
47          | Jim Bezdek    | NULL
111         | Vishal Gupta  | NULL
318         | Muaz A. Niazi | NULL
...         | ...           | ...  
...         | ...           | ...     

我有另一个作者-共同作者映射 table Yearly_Author_CoAuthors 为:

Author_ID | CoAuthor_ID | Year
------------------------------
677       | 901706      | 2005
677       | 838459      | 2007
677       | 901706      | 2007  
...       | ...         | ...  
...       | ...         | ...   

现在我必须在从 Authors table 获取的 CoAuthors table 中插入外键。问题是我可能有 CoAuthor_ID 的多个 Author_ID 值,例如执行此查询:

SELECT   
    Author_ID, CoAuthor_ID, Year  
FROM     
    Yearly_Author_CoAuthors  
WHERE
    CoAuthor = 901706  
ORDER BY 
    Author_ID, Year, CoAuthor_ID  

我得到了这个输出:

Author_ID | CoAuthor_ID | Year  
------------------------------
677       | 901706      | 2005
677       | 901706      | 2007
677       | 901706      | 2009
1683703   | 901706      | 2012  

这表明 CoAuthor_ID = 901706 有两个 DISTINCT Author_ID,所以这里:

如何在 CoAuthors table 中插入 Author_ID 作为外键约束?

只要 Author_ID 在作者 table 中是唯一的,作者和合著者之间潜在的多对多关系就不会阻止外键约束。只需这样做:

ALTER TABLE CoAuthors
ADD CONSTRAINT FK_Authors_Author_ID FOREIGN KEY (CoAuthor_ID) 
    REFERENCES Authors (Author_ID) 

查看您的示例 Yearly_Author_CoAuthors select 查询,您必须输入重复的值才能返回它们。

要么使 Author_ID & CoAuthor_ID 成为复合主键(没有年份),要么在这两列中添加唯一索引。

编辑: 如果您在 Yearly_Author_CoAuthors.Author_ID 和 Yearly_Author_CoAuthors.CoAuthor_ID 上没有外键,那么我建议您首先调整 user3481891 的答案中的脚本,将它们添加到 table。 那么我不明白为什么你不能查询你已经拥有的东西。以下是一些示例(恐怕未经测试,如果它们不起作用请告诉我):

-- to get list of who a CoAuthor has worked with and when
select  a.Author_Name,
        ca.CoAuthor_Name,
        [Year]
from    Authors a inner join 
        Yearly_Author_CoAuthors yac on a.Author_ID = yac.Author_ID inner join 
        CoAuthors ca on yac.CoAuthor_ID = ca.CoAuthor_ID
where   yac.CoAuthor = 901706

-- to get a list of first occasions when a CoAuthor has worked with each Author
select  a.Author_Name,
        ca.CoAuthor_Name,
        min([Year]) as FirstCollaborationDate
from    Authors a inner join 
        Yearly_Author_CoAuthors yac on a.Author_ID = yac.Author_ID inner join 
        CoAuthors ca on yac.CoAuthor_ID = ca.CoAuthor_ID
where   yac.CoAuthor = 901706
group by a.Author_Name,
        ca.CoAuthor_Name
order by min([Year])