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
相关产品推荐
相关产品推荐

