无法添加外键约束 - MySQL 错误 1215 (HY000)

Cannot add foreign key constraint - MySQL ERROR 1215 (HY000)

我正在尝试为健身房管理系统创建数据库,但我不明白为什么会出现此错误。我试图在这里搜索答案,但找不到。

ERROR 1215 (HY000): Cannot add foreign key constraint

CREATE TABLE sales(
    saleId int(100) NOT NULL AUTO_INCREMENT,
    accountNo int(100) NOT NULL,
    payName VARCHAR(100) NOT NULL,
    nextPayment DATE,
    supplementName VARCHAR(250),
    qty int(11),
    workoutName VARCHAR(100),
    sDate datetime NOT NULL DEFAULT NOW(),
    totalAmount DECIMAL(11,2) NOT NULL,
    CONSTRAINT PRIMARY KEY(saleId, accountNo, payName),
    CONSTRAINT FOREIGN KEY(accountNo) REFERENCES accounts(accountNo) ON DELETE CASCADE ON UPDATE CASCADE,
    CONSTRAINT FOREIGN KEY(payName) REFERENCES paymentFor(payName) ON DELETE CASCADE ON UPDATE CASCADE,
    CONSTRAINT FOREIGN KEY(supplementName) REFERENCES supplements(supplementName) ON DELETE CASCADE ON UPDATE CASCADE,
    CONSTRAINT FOREIGN KEY(workoutName) REFERENCES workouts(workoutName) ON DELETE CASCADE ON UPDATE CASCADE
);
    ALTER TABLE sales AUTO_INCREMENT = 2001;

这是父表。

CREATE TABLE accounts(
    accountNo int(100) NOT NULL AUTO_INCREMENT,
    accountType VARCHAR(100) NOT NULL,
    firstName VARCHAR(50) NOT NULL,
    lastName VARCHAR(60) NOT NULL,
    birthdate DATE NOT NULL,
    gender VARCHAR(7),
    city VARCHAR(50) NOT NULL,
    street VARCHAR(50),
    cellPhone VARCHAR(10),
    emergencyPhone VARCHAR(10),
    email VARCHAR(150) NOT NULL,
    description VARCHAR(350),
    occupation VARCHAR(50),
    createdOn datetime NOT NULL DEFAULT NOW(),
    CONSTRAINT PRIMARY KEY(accountNo)
);
    ALTER TABLE accounts AUTO_INCREMENT = 1001; 


CREATE TABLE supplements(
    supplementId int(100) NOT NULL AUTO_INCREMENT,
    supplementName VARCHAR(250) NOT NULL,
    manufacture VARCHAR(100),
    description VARCHAR(150),
    qtyOnHand INT(5),
    unitPrice DECIMAL(11,2),
    manufactureDate DATE,
    expirationDate DATE,
    CONSTRAINT PRIMARY KEY(supplementId, supplementName)
);
    ALTER TABLE supplements AUTO_INCREMENT = 3001;

CREATE TABLE workouts(
    workoutId int(100) NOT NULL AUTO_INCREMENT,
    workoutName VARCHAR(100) NOT NULL,
    description VARCHAR(7500) NOT NULL,
    duration VARCHAR(30),
    CONSTRAINT PRIMARY KEY(workoutId, workoutName)
);
    ALTER TABLE workouts AUTO_INCREMENT = 4001;



CREATE TABLE paymentFor(
    payId int(100) NOT NULL AUTO_INCREMENT,
    payName VARCHAR(100) NOT NULL,
    amount DECIMAL(11,2),
    CONSTRAINT PRIMARY KEY(payId, payName)
);
    ALTER TABLE paymentFor AUTO_INCREMENT = 5001;

你们能帮我解决这个问题吗?谢谢

要将字段定义为 foreign key,引用的 parent 字段必须定义索引。

根据关于 foreign key 约束的文档:

REFERENCES parent_tbl_name (index_col_name,...)

分别在workouts.workoutNamepaymentFor.paymentNamesupplements.supplementName上定义一个INDEX。并确保 child 列定义必须与其 parent 列定义相匹配。

更改workouts table定义如下:

CREATE TABLE workouts(
    workoutId int(100) NOT NULL AUTO_INCREMENT,
    workoutName VARCHAR(100) NOT NULL,
    description VARCHAR(7500) NOT NULL,
    duration VARCHAR(30),

    KEY ( workoutName ), -- <---- this is newly added index key

    CONSTRAINT PRIMARY KEY(workoutId, workoutName)
);

改变supplements table定义如下:

CREATE TABLE supplements(
    supplementId int(100) NOT NULL AUTO_INCREMENT,
    supplementName VARCHAR(250) NOT NULL,
    manufacture VARCHAR(100),
    description VARCHAR(150),
    qtyOnHand INT(5),
    unitPrice DECIMAL(11,2),
    manufactureDate DATE,
    expirationDate DATE,

    KEY ( supplementName ), -- <---- this is newly added index key

    CONSTRAINT PRIMARY KEY(supplementId, supplementName)
);

更改paymentFor table定义如下:

CREATE TABLE paymentFor(
    payId int(100) NOT NULL AUTO_INCREMENT,
    payName VARCHAR(100) NOT NULL,
    amount DECIMAL(11,2),

    KEY ( payName ), -- <---- this is newly added index key

    CONSTRAINT PRIMARY KEY(payId, payName)
);

现在,将 child table 定义更改为如下:

CREATE TABLE sales(
    saleId int(100) NOT NULL AUTO_INCREMENT,
    accountNo int(100) NOT NULL,
    payName VARCHAR(100) NOT NULL,
    nextPayment DATE,
    supplementName VARCHAR(250) NOT NULL,
    qty int(11),
    workoutName VARCHAR(100) NOT NULL,
    sDate datetime NOT NULL DEFAULT NOW(),
    totalAmount DECIMAL(11,2) NOT NULL,
    CONSTRAINT PRIMARY KEY(saleId, accountNo, payName),
    CONSTRAINT FOREIGN KEY(accountNo) 
       REFERENCES accounts(accountNo) 
       ON DELETE CASCADE ON UPDATE CASCADE,
    CONSTRAINT FOREIGN KEY(payName) 
       REFERENCES paymentFor(payName) 
       ON DELETE CASCADE ON UPDATE CASCADE,
    CONSTRAINT FOREIGN KEY(supplementName) 
       REFERENCES supplements(supplementName) 
       ON DELETE CASCADE ON UPDATE CASCADE,
    CONSTRAINT FOREIGN KEY(workoutName) 
       REFERENCES workouts(workoutName) 
       ON DELETE CASCADE ON UPDATE CASCADE
);

参考

[CONSTRAINT [symbol]] FOREIGN KEY
[index_name] (index_col_name, ...)
REFERENCES tbl_name (index_col_name,...)
[ON DELETE reference_option]
[ON UPDATE reference_option]

reference_option:
RESTRICT | CASCADE | SET NULL | NO ACTION

外键 是一种在不同 table 的列之间实现 relationships/constraints 的方法。

当从父级更新或删除行时,有不同类别的约束会影响它们的执行方式 table:

Cascade:如果从父项中删除一行,则子项 table 中具有匹配 FK 值的任何行也将被删除。同样对于更改父项中的值 table.

Restrict:不能从父项 table 中删除行,如果这会破坏与子项 table 的 FK 约束。同样对于更改父项中的值 table.

No Action:与“Restrict”非常相似,除了父 table 上的任何 events/triggers 都将在强制执行约束之前执行——让应用程序编写者可以选择使用存储过程解决任何 FK 约束冲突。

Set NULL:如果 NULL 是子 table 中 FK 列的允许值,那么如果父 table 中的关联数据是更新或删除。

Set Default:如果子 table 中的 FK 列有默认值,那么如果父 table 中的关联数据更新或删除。请注意,此版本中未实现 - 可以将约束添加到架构中,但对父 table 中的列进行的任何后续删除或更新都将失败。

如果您想找出错误的原因,您只需在命令下方 运行 并查找“LATEST FOREIGN KEY ERROR

命令 运行 :-

mysql> SHOW ENGINE INNODB STATUS

你会知道你犯这些错误的原因。

我不是在回答上述问题,而是为了那些 运行 会遇到同样 mysql 错误的人。

我所做的只是将引用的 table 引擎更改为 innodb。

有时您会收到此错误“#1215 - 无法添加外键约束”,因为 table TYPE (InnoDB, MyISAM,..) 不匹配。

所以把你的table改成相同的类型然后尝试申请外键约束

mysql> ALTER TABLE table_name ENGINE=InnoDB;

mysql> ALTER TABLE Orders ADD FOREIGN KEY (P_Id) REFERENCES Persons(P_Id)

我遇到了同样的错误。原因是我指的是 table 中使用 charset utf8 创建的 table 中的一个列,该 table 使用 charset latin.

使用 mySQL workbench 创建 table 实用程序创建的 table 具有默认拉丁字符集。

如果您使用 workbench,找出这一点的简单方法是查看任何 table 的 table 创建语句。您将在末尾有默认的字符集字符串。

这可能对某些人有用。只需将默认字符集添加为 utf8

DEFAULT CHARACTER SET = utf8;

我遇到此错误我为具有 'not null constraint' 的列添加了外键约束,但我在外约束中指定了 'on delete set null'。这是一个一开始可能并不明显的矛盾。

这是我的两个 table:

CREATE TABLE study (
    id int(11) NOT NULL AUTO_INCREMENT primary key,
    name varchar(100) NOT NULL,
    introduction text,
    objective varchar(250) DEFAULT NULL,
    method text,
    result text,
    conclusion varchar(250) DEFAULT NULL,
    future_action varchar(100) DEFAULT NULL
);

drop table client_study;
CREATE TABLE client_study (
      id int(11) NOT NULL AUTO_INCREMENT primary key,
      client_id int(11),
      study_id int(11) not null, --If delete 'not null' error goes away!
      contact_person int(11),
      effective_date datetime DEFAULT CURRENT_TIMESTAMP,
      trial_site int(11) DEFAULT NULL,
      UNIQUE KEY unqidx_client_study (client_id,study_id)
);

ALTER TABLE client_study
ADD CONSTRAINT FOREIGN KEY (study_id) REFERENCES study(id)
ON DELETE SET NULL ON UPDATE CASCADE;

ERROR 1215 (HY000): Cannot add foreign key constraint

如果在client_studytable中删除study_id列的NOT NULL约束,则可以添加外键。另一种选择是在 client_table 上保留非空约束,但将外键定义修改为 on delete no action 或其他选择。