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

Laravel迁移添加外键失败:errno:150外键约束格式错误排查

Laravel数据库迁移添加外键失败问题解决

问题场景

本地环境(PHP7.4.3+MySQL8.0.30)执行Laravel数据库迁移正常,但在虚拟主机环境(PHP7.3.33+MariaDB10.3.36)执行php artisan migrate时,添加外键操作失败。涉及两张表:media和video_categorie。

迁移文件代码

创建video_categorie表的迁移文件

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreateVideoCategorieTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('video_categorie', function (Blueprint $table) {
            $table->increments('id');
            $table->string('nom_fr', 50);
            $table->string('nom_en', 50)->nullable();
            $table->unsignedSmallInteger('ordre')->nullable();
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('video_categorie');
    }
}

为media表添加外键的迁移文件

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class AddForeignKeyToMediaTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::table('media', function (Blueprint $table) {
            $table->unsignedInteger('video_categorie_id')->nullable();
            $table->unsignedSmallInteger('ordre_video')->nullable();
            $table->foreign('video_categorie_id')->references('id')->on('video_categorie');
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::table('media', function (Blueprint $table) {
            $table->dropForeign('media_video_categorie_id_foreign');
            $table->dropColumn('video_categorie_id');
            $table->dropColumn('ordre_video');
        });
    }
}

迁移错误信息

执行php artisan migrate时触发的错误:

Migrating: 2022_09_15_092133_create_video_categorie_table
Migrated:  2022_09_15_092133_create_video_categorie_table (7.91ms)
Migrating: 2022_09_15_115815_add_foreign_key_to_media_table

   Illuminate\Database\QueryException

  SQLSTATE[HY000]: General error: 1005 Can't create table `stag_db`.`media` (errno: 150 "Foreign key constraint is incorrectly formed") (SQL: alter table `media` add constraint `media_video_categorie_id_foreign` foreign key (`video_categorie_id`) references `video_categorie` (`id`))

  at vendor/laravel/framework/src/Illuminate/Database/Connection.php:712
    708▕         // If an exception occurs when attempting to run a query, we'll format the error
    709▕         // message to include the bindings with SQL, which will make this exception a
    710▕         // lot more helpful to the developer instead of just the database's errors.
    711▕         catch (Exception $e) {
  ➜ 712▕             throw new QueryException(
    713▕                 $query, $this->prepareBindings($bindings), $e
    714▕             );
    715▕         }
    716▕     }

      +9 vendor frames
  10  database/migrations/2022_09_15_115815_add_foreign_key_to_media_table.php:20
      Illuminate\Support\Facades\Facade::__callStatic("table")

      +22 vendor frames
  33  artisan:37
      Illuminate\Foundation\Console\Kernel::handle(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))

迁移状态

| Yes  | 2022_08_18_135729_add_fichier_column_to_contact_table                                                | 32    |
| Yes  | 2022_08_29_120103_add_contact_motif_name_column_to_contact_table                                     | 33    |
| Yes  | 2022_09_15_092133_create_video_categorie_table                                                       | 33    |
| No   | 2022_09_15_115815_add_foreign_key_to_media_table                                                     |       |
| No   | 2022_09_15_120150_add_orph_video_column_to_media_table                                               |       |
+------+------------------------------------------------------------------------------------------------------+-------+

问题原因与解决方法

原因

虚拟主机默认数据库存储引擎为MyISAM,新建的video_categorie表使用了该引擎,而MyISAM不支持外键关联。

临时解决方法

手动执行SQL修改表引擎后,再重新执行迁移:

ALTER TABLE video_categorie ENGINE = InnoDB;

之后运行:

php artisan migrate

永久解决方法

联系主机商将数据库默认存储引擎改为InnoDB,确保后续新建表自动使用支持外键的引擎。

内容的提问来源于stack exchange,提问作者Petitemo

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 08:40:32