【问题标题】:Cannot add foreign key constraint - MySQL ERROR 1215 (HY000)无法添加外键约束 - MySQL ERROR 1215 (HY000)
【发布时间】:2015-03-25 05:24:15
【问题描述】:

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

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;

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

【问题讨论】:

标签: mysql foreign-keys


【解决方案1】:

如果你想知道为什么会出现这个错误,你所要做的就是运行下面的命令并查找“LATEST FOREIGN KEY ERROR

运行命令:-

mysql> SHOW ENGINE INNODB STATUS

您会知道出现此类错误的原因。

【讨论】:

  • 谢谢,帮了大忙!
  • @John Cargo 我一直在做这个,做这个,做这个,没有任何反应。我不知道我是在错误的地方运行它还是什么。
  • 它应该返回status 消息。你能告诉我,当你运行上面的代码时,输​​出是什么?
  • 太好了,这解决了我的问题。此命令的输出非常详细。知道如何使它简洁吗?
  • 这很有帮助
【解决方案2】:

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

根据foreign key 约束的文档:

REFERENCES parent_tbl_name (index_col_name,...)

分别在workouts.workoutNamepaymentFor.paymentNamesupplements.supplementName 上定义INDEX。并确保子列定义必须与其父列定义匹配。

修改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 [符号]] 外键
[index_name] (index_col_name, ...)
参考 tbl_name (index_col_name,...)
[ON DELETE reference_option]
[ON UPDATE reference_option]

reference_option:
限制 |级联 |设置空 |没有行动

【讨论】:

  • 非常感谢! @Ravinder
【解决方案3】:

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

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

Cascade:如果从父表中删除一行,则子表中具有匹配 FK 值的任何行也将被删除。对父表中的值进行更改也是如此。

Restrict:如果这会破坏子表的 FK 约束,则无法从父表中删除行。对父表中的值进行更改也是如此。

No Action:与“限制”非常相似,只是父表上的任何事件/触发器都将在强制执行约束之前执行——让应用程序编写者可以选择使用存储过程解决任何 FK 约束冲突。

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

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

【讨论】:

    【解决方案4】:

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

    所以把你的表类型改成相同的并尝试申请外键约束

    mysql&gt; ALTER TABLE table_name ENGINE=InnoDB;

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

    【讨论】:

      【解决方案5】:

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

      DEFAULT CHARACTER SET = utf8;
      

      【讨论】:

      • +1 - 这对我来说是个问题。原因是如果你有一个字符串类型的字段引用一个字符串类型的字段,它只能将两个索引链接在一起,如果它们使用相同的字符集。在我的情况下,其中一个表使用 utf8,另一个使用 latin1,因此将其更改为 utf8 可以解决此问题。
      【解决方案6】:

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

      使用 mySQL 工作台创建表实用程序创建的表具有默认的拉丁字符集。

      如果您使用的是工作台,最简单的方法是查看任何表的表创建语句。最后你会得到默认的字符集字符串。

      【讨论】:

        【解决方案7】:

        我不是在回答上面的问题,而只是针对会遇到同样 mysql 错误的人。

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

        【讨论】:

          【解决方案8】:

          我遇到此错误我为具有“非空约束”的列添加外键约束,但我在外约束中指定了“删除时设置为空”。这是一个矛盾,起初可能并不明显。

          这是我的两张桌子:

          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 上保留 not null 约束,但将外键定义修改为 on delete no action 或其他选择。

          【讨论】:

            猜你喜欢
            • 2013-09-26
            • 2014-03-27
            • 2018-09-09
            • 1970-01-01
            • 2014-08-24
            • 1970-01-01
            • 2021-09-24
            • 2017-09-01
            • 1970-01-01
            相关资源
            最近更新 更多