Laravel 9中users表state_id关联states表id迁移报错求助
解决Laravel 9中外键约束创建失败问题
使用Laravel 9框架,尝试将users表的state_id字段作为外键关联到states表的id字段,执行数据库迁移时触发错误,报错信息如下:
Illuminate\Database\QueryException SQLSTATE[HY000]: General error: 1005 Can't create table `digidb_final`.`companies` (errno: 150 "Foreign key constraint is incorrectly formed") (SQL: alter table `companies` add constraint `companies_state_id_foreign` foreign key (`state_id`) references `states` (`id`) on delete cascade) at E:\Projects\DigiTork-Final\vendor\laravel\framework\src\Illuminate\Database\Connection.php:759 755▕ // If an exception occurs when attempting to run a query, we'll format the error 756▕ // message to include the bindings with SQL, which will make this exception a 757▕ // lot more helpful to the developer instead of just the database's errors. 758▕ catch (Exception $e) { ➜ 759▕ throw new QueryException( 760▕ $query, $this->prepareBindings($bindings), $e 761▕ ); 762▕ } 763▕ } 1 E:\Projects\DigiTork-Final\vendor\laravel\framework\src\Illuminate\Database\Connection.php:544 PDOException::("SQLSTATE[HY000]: General error: 1005 Can't create table `digidb_final`.`companies` (errno: 150 "Foreign key constraint is incorrectly formed")") 2 E:\Projects\DigiTork-Final\vendor\laravel\framework\src\Illuminate\Database\Connection.php:544 PDOStatement::execute()
相关迁移代码
users表迁移代码
Schema::create('users', function (Blueprint $table) { $table->id(); $table->string('name'); $table->string('lname'); $table->string('NationalCode')->nullable(); $table->string('phone')->unique(); $table->string('Dateofbirth')->nullable(); $table->boolean('gender')->nullable(); $table->unsignedBigInteger('state_id'); $table->foreign('state_id')->references('id')->on('states')->onDelete('cascade'); $table->string('banknumber')->nullable(); $table->string('email')->unique(); $table->timestamp('email_verified_at')->nullable(); $table->string('password'); $table->rememberToken(); $table->timestamps(); });
states表迁移代码
Schema::create('states', function (Blueprint $table) { $table->id(); $table->string('state'); $table->string('city'); $table->boolean('active'); });
解决方案
- 调整迁移执行顺序:外键依赖的父表(states)必须先于子表(users/companies)创建。查看迁移文件的命名,文件名开头的时间戳决定执行顺序,确保states表的迁移文件时间戳早于users和companies表。若顺序错误,可重命名迁移文件修改时间戳,或把外键约束的创建单独放在一个新迁移文件中(需在states表迁移之后执行)。
- 确认字段类型完全匹配:子表外键字段的类型必须和父表主键字段完全一致。states表的
id是unsignedBigInteger(Laravel$table->id()默认类型),users表的state_id已使用unsignedBigInteger,这部分没问题,但需检查companies表的state_id是否也是相同类型,避免类型不匹配。 - 确保表使用InnoDB引擎:MySQL的MyISAM引擎不支持外键约束,必须使用InnoDB。Laravel默认使用InnoDB,若手动修改过引擎,需在迁移中明确指定:
同时给users和companies表也添加该设置。Schema::create('states', function (Blueprint $table) { $table->engine = 'InnoDB'; // 其他字段定义 }); - 排查companies表的关联问题:报错信息指向
companies表而非描述中的users表,需确认companies表的迁移代码中是否也有state_id外键关联,并确保该关联符合上述所有要求。
内容的提问来源于stack exchange,提问作者arash dm
相关产品推荐
相关产品推荐

