簡體   English   中英

復合主鍵中使用的外鍵

[英]Foreign Key Used in Composite Primary Key

是否可以將復合外鍵用作表的復合主鍵的一部分?

例如,假設我有兩個表:

CREATE TABLE DB.dbo.Partners
(
    CONSTRAINT pk_Partners_Id
    PRIMARY KEY (Name, City, State, Country, PostalCode),
    
    Name                VARCHAR(100)    NOT NULL,
    Address1            VARCHAR(100),   
    Address2            VARCHAR(100),   
    Address3            VARCHAR(100),   
    City                VARCHAR(150)    NOT NULL,   
    State               CHAR(2)         NOT NULL,   
    Country             CHAR(2)         NOT NULL,   
    PostalCode          VARCHAR(16)     NOT NULL,   
    Phone               VARCHAR(20),    
    Fax                 VARCHAR(20),    
    Email               VARCHAR(256)
)

...然后在第二個表中,我想引用第二個表的主鍵中的外鍵:

CREATE TABLE DB.dbo.PartnerContacts
(
    CONSTRAINT pk_PartnerContacts_Id
    PRIMARY KEY (fk_PartnerContacts_PartnerId, FirstName, LastName, PhoneNumber, Email),
                        
    CONSTRAINT fk_PartnerContacts_PartnerId
    FOREIGN KEY REFERENCES Partners(Name, City, State, Country, PostalCode),

    FirstName           VARCHAR(75)     NOT NULL,   
    MiddleName          VARCHAR(75),    
    LastName            VARCHAR(75)     NOT NULL,   
    PhoneNumber         VARCHAR(20)     NOT NULL,   
    MobileNumber        VARCHAR(20),    
    FaxNumber           VARCHAR(20),    
    Email               VARCHAR(256)    NOT NULL,   
    MailTo              VARCHAR(100),   
    Address1            VARCHAR(100),   
    Address2            VARCHAR(100),   
    Address3            VARCHAR(100),   
    City                VARCHAR(150),   
    State               CHAR(2),    
    Country             CHAR(2),    
    PostalCode          VARCHAR(16)
)

有什么辦法可以做到嗎? 是的,在這些表中簡單地使用 IDENTITY 列可能更容易,但如果我可以定義沒有 IDENTITY 的實際關系,我想這樣做。

編輯:

我想提供最終的、有效的 SQL。 感謝所有回答的人!

CREATE TABLE DB.dbo.Partners
(
    CONSTRAINT pk_Partners_Id
    PRIMARY KEY (Name, City, State, Country, PostalCode),
    
    Id                  INT             NOT NULL   UNIQUE   IDENTITY(1, 1),
    Name                VARCHAR(100)    NOT NULL,
    Address1            VARCHAR(100),   
    Address2            VARCHAR(100),   
    Address3            VARCHAR(100),   
    City                VARCHAR(150)    NOT NULL,   
    State               CHAR(2)         NOT NULL,   
    Country             CHAR(2)         NOT NULL,   
    PostalCode          VARCHAR(16)     NOT NULL,   
    Phone               VARCHAR(20),    
    Fax                 VARCHAR(20),    
    Email               VARCHAR(256)
)

CREATE TABLE DB.dbo.PartnerContacts
(
    CONSTRAINT pk_PartnerContacts_Id
    PRIMARY KEY
    (PartnerId, FirstName, LastName, PhoneNumber, Email),
                        
    PartnerId           INT             NOT NULL CONSTRAINT fk_PartnerContacts_PartnerId FOREIGN KEY    REFERENCES Partners(Id),
    FirstName           VARCHAR(75)     NOT NULL,
    MiddleName          VARCHAR(75),    
    LastName            VARCHAR(75)     NOT NULL,   
    PhoneNumber         VARCHAR(20)     NOT NULL,   
    MobileNumber        VARCHAR(20),    
    FaxNumber           VARCHAR(20),    
    Email               VARCHAR(256)    NOT NULL,
    MailTo              VARCHAR(100),   
    Address1            VARCHAR(100),   
    Address2            VARCHAR(100),   
    Address3            VARCHAR(100),   
    City                VARCHAR(150),   
    State               CHAR(2),    
    Country             CHAR(2),    
    PostalCode          VARCHAR(16)
)

您可能需要指定應該匹配的列。

CONSTRAINT fk_PartnerContacts_PartnerId
FOREIGN KEY         (columns that correspond to referenced columns) 
 REFERENCES Partners (Name, City, State, Country, PostalCode),

因此,您需要提供五個列名稱,其值應該與“合作伙伴”表中的 {Name, City, State, Country, PostalCode} 的值匹配。 我很確定你不能用你目前的結構做到這一點。 您將無法匹配“名稱”。 我認為你正在尋找類似這些的東西。

CREATE TABLE DB.dbo.PartnerContacts (
-- Start with columns that identify "Partner".
    partner_name VARCHAR(100) NOT NULL,
    partner_city VARCHAR(150) NOT NULL,
    partner_state CHAR(2) NOT NULL,
    partner_country CHAR(2) NOT NULL,
    partner_postcode VARCHAR(16) NOT NULL,
    CONSTRAINT fk_PartnerContacts_PartnerId
        FOREIGN KEY (partner_name, partner_city, partner_state, partner_country, partner_postcode) 
        REFERENCES Partners (Name, City, State, Country, PostalCode),
    FirstName    VARCHAR(75) NOT NULL,
    MiddleName   VARCHAR(75),
    LastName     VARCHAR(75) NOT NULL,
    PhoneNumber  VARCHAR(20) NOT NULL,
    MobileNumber VARCHAR(20),
    FaxNumber    VARCHAR(20),
    Email        VARCHAR(256) NOT NULL,
    MailTo       VARCHAR(100),
    Address1     VARCHAR(100),
    Address2     VARCHAR(100),
    Address3     VARCHAR(100),
    City         VARCHAR(150),
    State        CHAR(2),
    Country      CHAR(2),
    PostalCode   VARCHAR(16),
    CONSTRAINT pk_PartnerContacts_Id
    PRIMARY KEY (partner_name, partner_city, partner_state, partner_country, partner_postcode, 
                 FirstName, LastName, PhoneNumber, Email)
);

是的,這是可能的,通常被認為是最好的數據庫設計實踐,但實際上,ID 列更容易處理。 想想連接表,它們的主鍵是兩個外鍵的組合。 使用多個外鍵作為復合主鍵的一部分沒有區別。

是的,這絕對有可能。 我們確實有一些實例,其中我們有一個復合外鍵,它是其他表的復合主鍵的一部分。

對於下面的示例,讓我們稍微簡化一下用例。

假設我們有一個表 test1 有一個復合主鍵 (A, B)

現在我們可以有一個表,說 test2 具有主鍵 (P, Q, R),其中在 test2 的 (P,Q) 中引用了 test1 的 (A,B)。

我在 MySql 數據庫中運行了以下腳本,它工作得很好。

CREATE TABLE `test1` (
`A` INT NOT NULL,
`B` VARCHAR(2) NOT NULL,
`C` DATETIME NULL,
`D` VARCHAR(45) NULL,
PRIMARY KEY (`A`, `B`));


CREATE TABLE `test2` (
`P` INT NOT NULL,
`Q` VARCHAR(2) NOT NULL,
`R` INT NOT NULL,
`S` DATETIME NULL,
`T` VARCHAR(8) NULL,
PRIMARY KEY (`P`, `Q`, `R`),
INDEX `PQ_idx` (`P`,`Q` ASC),
CONSTRAINT `PQ`
  FOREIGN KEY (`P`, `Q`)
  REFERENCES `test1` (`A`,`B`)
  ON DELETE CASCADE
  ON UPDATE CASCADE);

在上述情況下,數據庫期望 (A,B) 的組合是唯一的,並且它是 test1 表中的主鍵。


但是,如果您嘗試執行以下操作,腳本將失敗。 數據庫不允許您創建 test2 表。

CREATE TABLE `test2` (
`P` INT NOT NULL,
`Q` VARCHAR(2) NULL,
`R` DATETIME NULL,
`S` VARCHAR(8) NULL,
`T` VARCHAR(45) NULL,
  INDEX `P_idx` (`P` ASC),
  INDEX `Q_idx` (`Q` ASC),
  CONSTRAINT `P`
    FOREIGN KEY (`P`)
    REFERENCES `test1` (`A`)
    ON DELETE CASCADE
    ON UPDATE CASCADE,
  CONSTRAINT `Q`
    FOREIGN KEY (`Q`)
    REFERENCES `test1` (`B`)
    ON DELETE CASCADE
    ON UPDATE CASCADE);

在上面提到的情況下,數據庫希望 A 列單獨是唯一的,B 列也是如此。 (A,B) 的組合是否唯一無關緊要。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM