You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel 8迁移报错errno:150「外键约束格式错误」问题求助

Laravel 8迁移报错errno:150「外键约束格式错误」问题求助

兄弟,我之前也踩过这个外键约束的坑!咱们先一步步拆解问题,看看哪里出了问题。

首先,你遇到的errno:150错误,在Laravel迁移里最常见的原因无非这几个:

  • 关联字段的数据类型/长度完全不匹配
  • 父表(也就是你的products表)的关联字段不是主键或未建立索引
  • 两张表的存储引擎不一致(只有InnoDB支持外键,MyISAM不行)
  • 迁移文件执行顺序颠倒(不过你已经确认products表先创建,这条可以排除)

咱们再对照你的代码来看:
你的products表用了$table->id(),这个方法在Laravel里等价于$table->bigIncrements('id'),也就是无符号BIGINT类型的主键。而你在product_exchanges里写的是$table->bigInteger('product_id')->unsigned(),看起来类型是匹配的,但可能是写法不规范或者引擎的问题导致报错。

给你两个靠谱的解决方案:

方案一:用Laravel官方推荐的外键语法(最省心)

直接替换product_exchanges表中product_id字段的代码,Laravel的foreignId()方法会自动帮你创建匹配类型的字段,还能一键关联父表:

Schema::create('product_exchanges', function (Blueprint $table) {
    $table->id();
    $table->dateTime('date');
    $table->double('amount')->unsigned();
    $table->integer('count_from')->unsigned();
    $table->integer('count_to')->unsigned();
    // 替换成这一行,自动关联products表的id,同时支持级联更新删除
    $table->foreignId('product_id')->constrained('products')->onUpdate('cascade')->onDelete('cascade');
    $table->timestamps();
});

方案二:手动指定字段类型+统一存储引擎

如果想保持手动写法,需要确保两点:

  1. 外键字段用unsignedBigInteger和父表的bigIncrements完全匹配
  2. 两张表都明确指定InnoDB引擎(避免数据库默认引擎是MyISAM)

修改后的products表迁移:

Schema::create('products', function (Blueprint $table) {
    $table->engine = 'InnoDB'; // 强制指定引擎
    $table->id();
    $table->text('name');
    $table->boolean('active')->default(1);
    $table->timestamps();
});

修改后的product_exchanges表迁移:

Schema::create('product_exchanges', function (Blueprint $table) {
    $table->engine = 'InnoDB'; // 强制指定引擎
    $table->id();
    $table->dateTime('date');
    $table->double('amount')->unsigned();
    $table->integer('count_from')->unsigned();
    $table->integer('count_to')->unsigned();
    $table->unsignedBigInteger('product_id'); // 用unsignedBigInteger匹配父表的bigIncrements
    $table->foreign('product_id')->references('id')->on('products')->onUpdate('cascade')->onDelete('cascade');
    $table->timestamps();
});

最后提醒一句:如果之前已经执行过迁移,记得先执行php artisan migrate:rollback回滚旧结构,再重新执行迁移php artisan migrate,避免旧表结构残留导致报错哦!

备注:内容来源于stack exchange,提问作者Moamen Ali

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.21 15:13:06