简体   繁体   English

复合主键中使用的外键

[英]Foreign Key Used in Composite Primary Key

Is it possible to use a composite foreign key as a piece of a table's composite primary key?是否可以将复合外键用作表的复合主键的一部分?

For instance, let's say I have two tables:例如,假设我有两个表:

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)
)

... and then in a second table, I would like to reference the foreign key in the second table's primary key: ...然后在第二个表中,我想引用第二个表的主键中的外键:

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)
)

Is there any way that I can do that?有什么办法可以做到吗? Yes, it might be easier to just simply use IDENTITY columns in these tables but if I can define an actual relationship without an IDENTITY I would like to do that.是的,在这些表中简单地使用 IDENTITY 列可能更容易,但如果我可以定义没有 IDENTITY 的实际关系,我想这样做。

EDIT:编辑:

I wanted to provide the final, working SQL.我想提供最终的、有效的 SQL。 Thanks to everyone who answered!感谢所有回答的人!

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)
)

You probably need to specify the columns that are supposed to match.您可能需要指定应该匹配的列。

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

So you need to provide the five column names whose values are supposed to match the values of {Name, City, State, Country, PostalCode} in the table "Partners".因此,您需要提供五个列名称,其值应该与“合作伙伴”表中的 {Name, City, State, Country, PostalCode} 的值匹配。 i'm pretty sure youcan't do that with your current structure.我很确定你不能用你目前的结构做到这一点。 You won't be able to match "Name".您将无法匹配“名称”。 I think you're looking for something along these lines.我认为你正在寻找类似这些的东西。

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

Yes it is possible and is generally considered best DB design practice, but practically, an ID column is just easier to deal with.是的,这是可能的,通常被认为是最好的数据库设计实践,但实际上,ID 列更容易处理。 Think of join tables, their primary key is a composite of two foreign keys.想想连接表,它们的主键是两个外键的组合。 There is no difference to using multiple foreign keys as part of a composite primary key.使用多个外键作为复合主键的一部分没有区别。

Yes, that is definitely possible.是的,这绝对有可能。 We do have instances where we have a composite foreign key that is a part of the composite primary key of other table.我们确实有一些实例,其中我们有一个复合外键,它是其他表的复合主键的一部分。

Let's simplify the use case little bit for the below example.对于下面的示例,让我们稍微简化一下用例。

Say we have a table test1 having a composite primary key (A, B)假设我们有一个表 test1 有一个复合主键 (A, B)

Now we can have a table say test2 having primary key (P, Q, R) where in (P,Q) of test2 references (A,B) of test1.现在我们可以有一个表,说 test2 具有主键 (P, Q, R),其中在 test2 的 (P,Q) 中引用了 test1 的 (A,B)。

I ran the following script in the MySql database and it works just fine.我在 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);

In the above mentioned case, the database is expecting the combination of (A,B) to be unique and it is, being a primary key in test1 table.在上述情况下,数据库期望 (A,B) 的组合是唯一的,并且它是 test1 表中的主键。


But if you try to do something like following, the script would fail.但是,如果您尝试执行以下操作,脚本将失败。 The database would not let you create the test2 table.数据库不允许您创建 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);

In the above mentioned case database would expect the column A to be unique individually and the same follows for column B. It does not matter if combination of (A,B) is unique.在上面提到的情况下,数据库希望 A 列单独是唯一的,B 列也是如此。 (A,B) 的组合是否唯一无关紧要。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM