SQL:外键引用复合主键

cyb*_*bel 4 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)
);
Run Code Online (Sandbox Code Playgroud)

我知道要创建另一个表,该表具有表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)
);
Run Code Online (Sandbox Code Playgroud)

由于某种原因,这不起作用,每次都会出现错误。我已经在stackoverflow上查找了其他线程,但是它们似乎并没有帮助我。我究竟做错了什么?

mar*_*c_s 6

如果您有一个由三列组成的复合PK,则任何想要建立外键关系的子表都必须同时拥有这三列,并使用所有三列来建立FK关系。

FK-PK关系是一个全有或全无的提议-您不能仅引用主键的一部分-您可以引用所有列-或不引用。

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)
);
Run Code Online (Sandbox Code Playgroud)


Gor*_*off 6

有一个整数主键,使用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)
);
Run Code Online (Sandbox Code Playgroud)

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

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

笔记:

  • 您确实不想处理复合主键。您是否想过连接会是什么样子?
  • 您不希望主键的值可能会发生变化。当某人更改姓名时会发生什么?当有人动的时候?
  • Person不应该是 中的主键Purchases。您是否只允许某人购买一件商品?
  • 正如最初所指出的,生成此类列的方式因数据库而异。identitySQL Server 恰好就是这样做的。

  • 这个解决方案更像现实世界:) (2认同)