6

我有一个“主表”,称之为Customers

 CREATE TABLE Customers (
     CustomerID int PRIMARY KEY NOT NULL,
     FirstName nvarchar(50),
     LastName nvarchar(50)
 )

在此处输入图像描述

我有一个“卫星表”,称之为Customer_IllegallyObtainedInformation

CREATE TABLE Customer_IllegallyObtainedInformation (
    CustomerID int PRIMARY KEY NOT NULL,
    CellPhonePin int,
    SexualOrientation varchar(20),
    EmailPassword varchar(50)
)

在此处输入图像描述

现在,我想要的是从Illegal表回到主Customers表的外键约束:

在此处输入图像描述

换句话说:

  • 可以有一个Customer 没有Illegal条目_
  • 永远不可能没有一个Illegal条目Customer

我的直觉是,在 SQL Server 数据库图中,将

  • Illegal桌子Customers桌子_ _

向 SQL Server 表明Customers_IllegallyObtainedInformation关系中的“子”。相反,SQL Server 中发生的事情使其成为一对一的关系:

在此处输入图像描述

这意味着如果您尝试插入 a Customer,它将失败,因为没有现有Illegal信息。

如何在 SQL Server 中创建“父子”“一对一”关系?


注意:不要将示例与问题混淆。我可以在表中创建一个牺牲的主代理键Illegal

在此处输入图像描述

但这不是我的问题。

4

3 回答 3

8

似乎设计师正在相反的方向创建外键。

只需自己编写代码:

 CREATE TABLE Customers (
         CustomerID int PRIMARY KEY NOT NULL,
         FirstName nvarchar(50),
         LastName nvarchar(50)
     )

    CREATE TABLE Customer_IllegallyObtainedInformation (
        CustomerID int PRIMARY KEY NOT NULL,
        CellPhonePin int,
        SexualOrientation varchar(20),
        EmailPassword varchar(50),

        constraint fk_Customers foreign key (CustomerId) references dbo.Customers
    )

    -- succeeds:
    insert into dbo.Customers
        values(1, 'One', 'One'), (2, 'Two', 'Two')

    --fails:
    insert into dbo.Customer_IllegallyObtainedInformation
        values(3, 1, '', '');

    --succeeds:
    insert into dbo.Customer_IllegallyObtainedInformation
        values(1, 1, '', '');
于 2012-10-31T21:32:58.343 回答
5

PRIMARY KEY 可以参与出站 FOREIGN KEY 关系。

CREATE TABLE Customer_IllegallyObtainedInformation (
    CustomerID int PRIMARY KEY NOT NULL,
    CellPhonePin int,
    SexualOrientation varchar(20),
    EmailPassword varchar(50)
)
ALTER TABLE Customer_IllegallyObtainedInformation ADD FOREIGN KEY (CustomerId)
        REFERENCES Customer(CustomerId)
于 2012-10-31T21:37:11.170 回答
4

其他人已经指出如何通过使用 SQL 脚本设置关系来实现您想要的。我想我会添加我的几分钱关于设计师在做什么......

基本上你拖错了方向。

外键本身始终是一对多的。这是一种通知 DBMS 您有一个表(子表)的方法,您希望其中的列(或列的组合)始终对应于另一个表中的键。有了这些信息,DBMS 就可以接管确保子表中的每一行都真正满足这个要求的责任。

通过使列也成为子表中的键,可以使关系事实上是一对一的,但从 DBMS 的角度来看,这并不是关系的真正属性。相反,它只是对可以插入子表的数据的又一限制。

在设计器中创建关系时,似乎有人决定将主键拖到子表中。因此,当您从Customers_IllegallyObtainedInformation拖动到Customers时,设计器会认为Customers_IllegallyObtainedInformation是包含主键的表。

但是等等,为什么它在您引入代理键的第二个示例中起作用?可能是因为制作设计师的人决定让它变得聪明。在这种情况下,您拖动的列不是表中的键。这不能形成关系中的主键,因此设计者检查关系是否可以在相反的方向形成。既然可以,那就是它提供的...

于 2012-11-01T09:01:14.073 回答