我试图将我的新模式转发到我的数据库服务器上,但我不知道为什么我会得到这个错误。

我试图在这里寻找答案,但我所找到的一切都表明,要么将数据库引擎设置为InnoDB,要么确保我试图用作外键的键是它们自己表中的主键。如果我没记错的话,这两件事我都做过。我还能做什么?

Executing SQL script in server

ERROR: Error 1215: Cannot add foreign key constraint

-- -----------------------------------------------------
-- Table `Alternative_Pathways`.`Clients_has_Staff`
-- -----------------------------------------------------
CREATE  TABLE IF NOT EXISTS `Alternative_Pathways`.`Clients_has_Staff` (
  `Clients_Case_Number` INT NOT NULL ,
  `Staff_Emp_ID` INT NOT NULL ,
  PRIMARY KEY (`Clients_Case_Number`, `Staff_Emp_ID`) ,
  INDEX `fk_Clients_has_Staff_Staff1_idx` (`Staff_Emp_ID` ASC) ,
  INDEX `fk_Clients_has_Staff_Clients_idx` (`Clients_Case_Number` ASC) ,
  CONSTRAINT `fk_Clients_has_Staff_Clients`
    FOREIGN KEY (`Clients_Case_Number` )
    REFERENCES `Alternative_Pathways`.`Clients` (`Case_Number` )
    ON DELETE NO ACTION
    ON UPDATE NO ACTION,
  CONSTRAINT `fk_Clients_has_Staff_Staff1`
    FOREIGN KEY (`Staff_Emp_ID` )
    REFERENCES `Alternative_Pathways`.`Staff` (`Emp_ID` )
    ON DELETE NO ACTION
    ON UPDATE NO ACTION)
ENGINE = InnoDB

SQL脚本执行完成:语句:7成功,1失败

下面是父表的SQL。

CREATE  TABLE IF NOT EXISTS `Alternative_Pathways`.`Clients` (
  `Case_Number` INT NOT NULL ,
  `First_Name` CHAR(10) NULL ,
  `Middle_Name` CHAR(10) NULL ,
  `Last_Name` CHAR(10) NULL ,
  `Address` CHAR(50) NULL ,
  `Phone_Number` INT(10) NULL ,
  PRIMARY KEY (`Case_Number`) )
ENGINE = InnoDB

CREATE  TABLE IF NOT EXISTS `Alternative_Pathways`.`Staff` (
  `Emp_ID` INT NOT NULL ,
  `First_Name` CHAR(10) NULL ,
  `Middle_Name` CHAR(10) NULL ,
  `Last_Name` CHAR(10) NULL ,
  PRIMARY KEY (`Emp_ID`) )
ENGINE = InnoDB

当前回答

当使用Laravel迁移时尝试创建外键时,就像下面的例子:

用户表

public function up()
{
    Schema::create('flights', function (Blueprint $table) {
        $table->increments('id');
        $table->string('name');
        $table->TinyInteger('color_id')->unsigned();
        $table->foreign('color_id')->references('id')->on('colors');
        $table->timestamps();
    });
}

颜色表

public function up()
{
    Schema::create('flights', function (Blueprint $table) {
        $table->increments('id');
        $table->string('color');
        $table->timestamps();
    });
}

有时候属性不起作用:

[PDOException]
SQLSTATE[HY000]: General error: 1215 Cannot add foreign key constraint

发生此错误是因为[用户表]中的外键(类型)与[颜色表]中的主键(类型)不同。

要解决这个问题,你应该改变[colors table]中的主键:

($ table - > tinyIncrements’id’);


当你使用主键$table->Increments('id');时,你应该使用Integer作为外键:

$table->unsignedInteger('fk_id');
$table->foreign('fk_id')->references('id')->on('table_name');

$table->tinyIncrements('id');你应该使用unsignedTinyInteger作为外键:

$table->unsignedTinyInteger('fk_id');
$table->foreign('fk_id')->references('id')->on('table_name');

当你使用主键$table->smallIncrements('id');你应该使用unsignedSmallInteger作为外键:

$table->unsignedSmallInteger('fk_id');
$table->foreign('fk_id')->references('id')->on('table_name');

当你使用主键$table->mediumIncrements('id');你应该使用unsignedMediumInteger作为外键:

$table->unsignedMediumInteger('fk_id');
$table->foreign('fk_id')->references('id')->on('table_name');

其他回答

我只是想为VARCHAR外键关系添加这种情况。我花了上周的时间在MySQL Workbench 8.0中试图解决这个问题,最终能够修复这个错误。

简短的回答: 模式、表、列、引用表、引用列和引用父表的任何其他表的字符集和排序规则必须匹配。

长一点的回答: 我的表中有一个ENUM数据类型。我将此更改为VARCHAR,我可以从引用表中获取值,这样我就不必更改父表来添加额外的选项。这个外键关系看起来很简单,但我得到了1215错误。Arvind的回答和下面的链接建议使用

SHOW ENGINE INNODB STATUS;

在使用这个命令时,我得到了以下详细的错误描述,没有其他有用的信息

Cannot find an index in the referenced table where the referenced columns appear as the first columns, or column types in the table and the referenced table do not match for constraint. Note that the internal storage type of ENUM and SET changed in tables created with >= InnoDB-4.1.12, and such columns in old tables cannot be referenced by such columns in new tables. Please refer to http://dev.mysql.com/doc/refman/8.0/en/innodb-foreign-key-constraints.html for correct foreign key definition.

之后,我使用SET FOREIGN_KEY_CHECKS=0;正如Arvind Bharadwaj所建议的,链接在这里:

这给出了以下错误信息:

错误码:1822。日志含义添加外键约束失败。失踪 约束索引

在这一点上,我对模式进行了“逆向工程”,并且能够在EER图中创建外键关系。在'forward engineer'-ing上,我得到了以下错误:

错误1452:不能添加或更新子行:外键约束 失败

当我将EER图“转发工程”到一个新模式时,SQL脚本运行时没有出现问题。通过比较转发工程师尝试生成的SQL,我发现不同之处在于字符集和排序规则。父表、子表和两列具有utf8mb4字符集和utf8mb4_0900_ai_ci排序规则,然而,父表中的另一列使用character set = utf8, COLLATE = utf8_bin引用;到不同的子表。

对于整个模式,我更改了所有表和所有列的字符集和排序规则如下:

CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci;

这最终解决了我1215错误的问题。

注: 排序规则utf8mb4_general_ci适用于MySQL Workbench 5.0或更高版本。排序utf8mb4_0900_ai_ci仅适用于MySQL Workbench 8.0或更高版本。我相信我遇到字符集和排序问题的原因之一是由于MySQL Workbench升级到8.0之间。这里有一个链接,详细介绍了这种排序方式。

也要注意反节拍音的使用。我在一个脚本中有如下语句

ALTER TABLE service ADD FOREIGN KEY (create_by) REFERENCES `system_user(id)`;

但最后的反节拍是假的。它应该是:

ALTER TABLE service ADD FOREIGN KEY (create_by) REFERENCES `system_user`(`id`);

不幸的是MySQL没有给出这个错误的任何细节…

在我的情况下,我不得不禁用外键检查,因为源表不存在。

设置FOREIGN_KEY_CHECKS = 0;

在使用Laravel 4时,特别是使用JeffreyWay的Laravel 4生成器时,我遇到了一个“错误1215:不能添加外键约束”的陷阱。

在Laravel 4中,您可以使用JeffreyWay的Generators生成迁移文件,逐个创建表,这意味着每个迁移文件生成一个表。

您必须意识到这样一个事实,即每个迁移文件在文件名中都有一个时间戳,它给出了文件的顺序。生成的顺序也是当你触发Artisan CLI命令php Artisan migrate时迁移操作的顺序。

因此,如果一个文件请求一个指向后一个文件中将生成但尚未生成的键的外键约束,Error 1215将被触发。

在这种情况下,您需要调整迁移文件生成的顺序。按正确顺序生成新文件,复制内容,然后删除无序的旧文件。

我猜是客户。Case_Number和/或Staff。Emp_ID与Clients_has_Staff的数据类型不完全相同。Clients_Case_Number和Clients_has_Staff.Staff_Emp_ID。

也许父表中的列是INT UNSIGNED?

两个表中的数据类型必须完全相同。