SQL:外键引用复合主键

时间:2017-04-06 19:14:00

标签: sql

我是SQL新手,有很多事情发生,我似乎还不太明白。我有下表

CREATE TABLE Person 
(
    First_Name varchar(20) NOT NULL,
    Name varchar(20) NOT NULL,
    Address varchar(50) NOT NULL,

    PRIMARY KEY (First_Name, Name, Address)
);

我知道要创建另一个表,其中包含表Person作为外键的主键以及主键:

CREATE TABLE Purchase 
(
    No_Installments int,
    Rate int,
    Person varchar(50) NOT NULL PRIMARY KEY,

    CONSTRAINT PFK 
        FOREIGN KEY (Person) REFERENCES Person (First_Name, Name, Address)
);

由于某些原因,这不起作用,每次都会出错。我已经在stackoverflow上查找了其他主题,但他们似乎并没有真正帮助我。我做错了什么?

3 个答案:

答案 0 :(得分:4)

如果你有一个由三列组成的复合PK ,那么任何想要建立外键关系的子表都必须所有这三列<和< strong>使用所有3列来建立FK关系。

FK-PK关系是一个全有或全无提案 - 您不能仅引用主键的部分内容 - 您可以引用所有列 - 或者您不需要&#39;参考。

CREATE TABLE Purchase 
(
    No_Installments int,
    Rate int,

    Person varchar(50) NOT NULL PRIMARY KEY,

    First_Name varchar(20) NOT NULL,
    Name varchar(20) NOT NULL,
    Address varchar(50) NOT NULL,

    CONSTRAINT PFK 
        FOREIGN KEY (First_Name, Name, Address) 
        REFERENCES Person (First_Name, Name, Address)
);

答案 1 :(得分:2)

使用identityauto_incrementserial或其他适合您的数据库的整数主键:

CREATE TABLE Person (
    PersonId int identity PRIMARY KEY
    First_Name varchar(20) NOT NULL,
    Name varchar(20) NOT NULL,
    Address varchar(50) NOT NULL,
    CONSTRAINT unq_person_3 UNIQUE (First_Name, Name, Address)
);

然后使用标识列作为参考:

CREATE TABLE Purchase (
    PurchaseId int identity PRIMARY KEY,
    No_Installments int,
    Rate int,
    PersonId int,
    CONSTRAINT PFK 
        FOREIGN KEY (PersonId) REFERENCES Person (PersonId)
);

注意:

  • 您真的不想处理复合主键。你有没有考虑过连接会是什么样的?
  • 您不希望主键值可能会发生变化。当有人改变他/她的名字会发生什么?当有人移动?
  • Person不应该是Purchases中的主键。你只允许某人购买吗?
  • 如前所述,生成此类列的方式因数据库而异; identity恰好是SQL Server执行此操作的方式。

答案 2 :(得分:0)

您可能希望为每个人分配一个唯一的ID,而不是依赖于他们的名称是唯一的,或者是否需要一个地址。该ID将是您的主键和外键。您的购买表也应该有自己的主键ID - 否则因为主键必须是唯一的,每个人只能购买一次。

CREATE TABLE Person (
   id serial NOT NULL,
   First_Name varchar(20) NOT NULL,
   Name varchar(20) NOT NULL,
   Address varchar(50) NOT NULL,
   PRIMARY KEY (id));

CREATE TABLE Purchase (
   id serial NOT NULL,
   No_Installments int,
   Rate int,
   Person int NOT NULL,
   FOREIGN KEY (Person) REFERENCES Person (id), 
   PRIMARY KEY (id));