外键约束格式不正确

问题描述

我遇到了一个问题,我无法创建一些表,因为它们的外键“格式不正确”。我不知道为什么会出现此错误,因为键的类型相同且名称唯一。代码非常简单:

CREATE TABLE Vehicle(
        vin VARCHAR(25),ID VARCHAR(20),make VARCHAR(20),model VARCHAR(20),year_ VARCHAR(20),condition_ VARCHAR(20),PRIMARY KEY(vin,ID),FOREIGN KEY(ID) REFERENCES Listing(CarID)
        );

CREATE TABLE Listing(
        CarID VARCHAR(20),state_ VARCHAR(20),price INT(10),url VARCHAR(50),PRIMARY KEY(CarID),FOREIGN KEY(CarID) REFERENCES Vehicle(ID)
        );

解决方法

如果 Vehicle 的主键是 (vin,ID),那么引用它的外键也必须有两列,顺序相同,数据类型相同。

但在您的情况下,您的 Listing 表没有 vin 列,因此它无法引用 Vehicle 的主键。

Listing 引用 Vehicle 的部分主键意味着什么?不能保证在 Vehicle 中只存在具有给定值 ID 的一行。它可以有多行具有相同的 ID 和不同的 vin 值。因此,Listing 可能是多个车辆的子代,这可能没有意义。

所以你必须:

  • 在列表中添加一个 vin 列,这样它的外键就可以通过它的主键(两列)精确引用一行。

  • 修改 Vehicle 表,使 ID 单独成为其主键。


更新:

我刚刚注意到您在两个表中似乎都有外键。这通常不需要。当我考虑您要建模的内容时,我猜列表有一个或多个车辆,对吗?所以 Vehicle 应该引用它的父 Listing。但是 Listing 不需要引用 Vehicle。

所以以下工作:

首先创建父表,因为在父表存在之前你不能做外键。在您的情况下,Listing 是父表。

CREATE TABLE Listing(
    CarID VARCHAR(20),state_ VARCHAR(20),price INT(10),url VARCHAR(50),PRIMARY KEY(CarID)
    );

然后创建子表,使用引用其父表的外键。

CREATE TABLE Vehicle(
    vin VARCHAR(25),ID VARCHAR(20),make VARCHAR(20),model VARCHAR(20),year_ VARCHAR(20),condition_ VARCHAR(20),PRIMARY KEY(vin,ID),FOREIGN KEY(ID) REFERENCES Listing(CarID)
    );

我在 MySQL 5.7.27 上测试过。

,

这是正确的方法:

CREATE TABLE Vehicle(
        vin VARCHAR(25),ID)
        );

CREATE TABLE Listing(
        CarVin VARCHAR(25),CarID VARCHAR(20),PRIMARY KEY(CarVin,CarID),FOREIGN KEY(CarVin,CarID) REFERENCES Vehicle(vin,ID)
        );

在您的数据模型中有一个列表和车辆。

车辆可以在列表中(也可以不在列表中)。 Listing 有 n 辆车(所以你有一个 1 到 n 的关系)。

Listing 中的每一行都有一个车辆的引用,因此它需要车辆主键字段(或一些唯一字段)来引用它(车辆主键由“vin”和“ID”字段复合而成)。

所以Listing中的主键也应该由“vin”和“ID”复合而成,就像Vehicle的表一样。 使用整数自增字段作为每个表的主键是一个好习惯

您需要在表 Listing 中添加“CarVin”字段,然后 Listing 中的外键将为 FOREIGN KEY(CarVin,ID)

当您插入 Listing 行时,外键将检查是否存在值为 CarVin 和 CarID 的车辆。

要在表 Vehicle 中添加外键,您应该禁用外键检查 (SET FOREIGN_KEY_CHECKS=0;),直到创建表,因为表 Listing 尚不存在(如果您创建第一个表 Vehicle)。但我认为在这种情况下没有意义,至少您要确保所有车辆都在 Listing 表中。

要插入数据,您必须先插入车辆,然后将其添加到Listing表中(检查外键,至少直到最后禁用外键检查),否则外键检查将失败。

在@"Bill Karwin" 的模型中,您需要先插入 Listing 行,然后插入 Vehicle。

MySql foreign key constraint documentation,MySql中各个存储引擎对外键约束的实现方式不同。

两个表相互有外键约束:

SET FOREIGN_KEY_CHECKS=0; 

CREATE TABLE Vehicle(
        vin VARCHAR(25),FOREIGN KEY(vin,ID) REFERENCES Listing(CarVin,CarID)
        );

CREATE TABLE Listing(
        CarVin VARCHAR(25),ID)
        );

SET FOREIGN_KEY_CHECKS = 1;