Создание ограничения "один к одному" в SQL Server

у меня есть "основной таблицы", назовем его Customers:

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

enter image description here

и у меня есть "спутниковые стол", назовем его Customer_IllegallyObtainedInformation:

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

enter image description here

теперь, что я хочу является ограничением внешнего ключа от Illegal таблица назад к основному Customers стол:

enter image description here

другими словами:

  • здесь can будь Customer без an Illegal запись
  • но никогда быть Illegal запись без Customer

моим инстинктом было, в диаграмме базы данных SQL Server, перетащить

  • С the Illegal стол до the Customers таблица

указание SQL Server, что Customers_IllegallyObtainedInformation является "ребенком" в отношениях. Вместо этого то, что происходит в этом SQL Server, делает его отношением "один к одному":

enter image description here

это означает, что если вы попытаетесь вставить Customer, он потерпит неудачу, потому что нет существующего Illegal информация.

как я могу создать "Родитель-Ребенок" или "один-ко-дополнительный-один" отношения в SQL Server?


Примечание: не путайте пример с вопросом. я мог бы создать жертвенный первичный суррогатный ключ в Illegal стол:

enter image description here

3 ответов


другие уже указали, как вы можете получить то, что хотите, настроив отношения с помощью сценариев SQL. Я думал, что просто добавлю свои несколько центов о том, что делает дизайнер...

в основном вы перетаскиваете в неправильном направлении.

внешний ключ сам по себе всегда один-ко-многим. Это способ информирования СУБД о том, что у вас есть таблица (дочерняя таблица) , где вы хотите, чтобы столбец (или комбинация столбцов) всегда соответствовал ключу из другая таблица. С этой информацией СУБД может взять на себя ответственность за то, чтобы каждая строка в дочерней таблице фактически выполняла это требование.

сделав столбец ключом также в дочерней таблице, отношение может быть сделано де-факто один к одному, но с точки зрения СУБД это на самом деле не является свойством отношения. Скорее это еще одно ограничение на данные, которые могут быть вставлены в дочернюю таблицу.

при создании отношения в конструкторе, похоже, кто-то решил, что первичный ключ следует перетащить в дочернюю таблицу. Поэтому, когда вы перетаскиваете из Customers_IllegallyObtainedInformation to клиенты конструктор цифры Customers_IllegallyObtainedInformation - это таблица, содержащая первичный ключ.

но подождите, почему он работал со вторым образцом, где вы ввели суррогатный ключ? Вероятно, потому что люди, делающие дизайнер решил сделать его умным. В этом случае вы перетаскиваете столбец, который не является ключом в таблице. Это не может сформировать первичный ключ в отношении, поэтому конструктор проверяет, может ли отношение быть сформировано в противоположном направлении. И поскольку это возможно, это то, что он предлагает...


кажется, дизайнер создает внешний ключ в противоположном направлении.

просто сам код:

 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, '', '');

первичный ключ может участвовать в связи исходящего внешнего ключа.

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)