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

时间:2015-03-25 05:24:16

标签: mysql foreign-keys

我正在尝试为健身房管理系统创建数据库,但我无法弄清楚为什么我会收到此错误。我试图在这里寻找答案,但我无法找到它。

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;

你们可以帮我解决这个问题吗?感谢。

8 个答案:

答案 0 :(得分:30)

如果你想知道,为什么会出现这个错误,你所要做的就是在命令下运行并寻找“最新的外键错误

要运行的命令: -

mysql> SHOW ENGINE INNODB STATUS

您将知道此类错误的原因。

答案 1 :(得分:21)

对于要定义为foreign key的字段,引用的父字段必须在其上定义索引。

根据foreign key约束的文档:

  

REFERENCES parent_tbl_name(index_col_name,...)

分别在INDEXworkouts.workoutNamepaymentFor.paymentName上定义supplements.supplementName。并确保子列定义必须与其父列定义匹配。

更改workouts表定义如下:

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表定义如下:

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表定义如下:

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

现在,更改子表定义如下:

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,...)
      参考文献tbl_name(index_col_name,...)
      [ON DELETE reference_option]
      [ON UPDATE reference_option]

     

reference_option:
      限制| CASCADE | SET NULL |没有行动

答案 2 :(得分:4)

外键是一种在不同表中的列之间实现关系/约束的方法。

当从父表中更新或删除行时,有不同类别的约束会影响它们的实施方式:

Cascade:如果从父项中删除了一行,那么子表中具有匹配FK值的任何行也将被删除。类似地,更改父表中的值。

Restrict:如果这会破坏子表的FK约束,则无法从父表中删除行。类似地,更改父表中的值。

No Action:非常类似于“限制”,除了在强制执行约束之前将执行父表上的任何事件/触发器 - 为应用程序编写者提供使用存储解决任何FK约束冲突的选项过程

Set NULL:如果NULL是子表中FK列的允许值,则如果更新或删除父表中的关联数据,则将其设置为NULL。

Set Default:如果子表中的FK列存在默认值,则在更新或删除父表中的关联数据时将使用该值。请注意,此版本未在此版本中实现 - 可以将约束添加到架构中,但对父表中列的任何后续删除或更新都将失败。

答案 3 :(得分:3)

有些时候,由于表TYPE(InnoDB,MyISAM,..)不匹配,您将收到此错误“#1215 - 无法添加外键约束”。

因此,将您的表类型更改为相同并尝试申请外键约束

mysql> ALTER TABLE table_name ENGINE=InnoDB;

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

答案 4 :(得分:2)

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

即可
DEFAULT CHARACTER SET = utf8;

答案 5 :(得分:1)

我得到了同样的错误。原因是我指的是使用charset latin创建的表中使用charset utf8创建的表中的列。

使用mySQL workbench create table实用程序创建的表具有默认的charset latin。

如果您正在使用工作台,那么很容易找到它的方法是查看任何表的表create语句。您将在最后有默认的字符集字符串。

答案 6 :(得分:0)

我没有回答上述问题,只是针对会遇到同样的mysql错误的人。

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

答案 7 :(得分:0)

我遇到这个错误我为具有&#39;非空约束的列添加了外键约束&#39;但是我在删除集上指定了&#39; null&#39;在外国约束。这是一个矛盾,起初可能并不明显。

以下是我的两张表:

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_study表中study_id列的NOT NULL约束,则可以添加外键。另一种方法是在client_table上保留非null约束,但修改外键定义为on delete delete no action或其他选择。