迁移我的数据库时出现此错误,下面是我的代码,后面是我在尝试运行迁移时遇到的错误。
码
public function up()
{
Schema::create('meals', function (Blueprint $table) {
$table->increments('id');
$table->integer('user_id')->unsigned();
$table->integer('category_id')->unsigned();
$table->string('title');
$table->string('body');
$table->string('meal_av');
$table->timestamps();
$table->foreign('user_id')
->references('id')
->on('users')
->onDelete('cascade');
$table->foreign('category_id')
->references('id')
->on('categories')
->onDelete('cascade');
});
}
错误信息
[Illuminate\Database\QueryException]
SQLSTATE[HY000]: General error: 1005 Can't create table `meal`.`#sql-11d2_1
4` (errno: 150 "Foreign key constraint is incorrectly formed") (SQL: alter
table `meals` add constraint meals_category_id_foreign foreign key (`catego
ry_id`) references `categories` (`id`) on delete cascade)
在Laravel中创建新表时。将生成迁移,如:
$table->bigIncrements('id');
而不是(在较旧的Laravel版本中):
$table->increments('id');
使用bigIncrements
时,外键需要bigInteger而不是整数。所以你的代码看起来像这样:
public function up()
{
Schema::create('meals', function (Blueprint $table) {
$table->increments('id');
$table->unsignedBigInteger('user_id'); //changed this line
$table->unsignedBigInteger('category_id'); //changed this line
$table->string('title');
$table->string('body');
$table->string('meal_av');
$table->timestamps();
$table->foreign('user_id')
->references('id')
->on('users')
->onDelete('cascade');
$table->foreign('category_id')
->references('id')
->on('categories')
->onDelete('cascade');
});
}
你也可以使用increments
代替bigIncrements
,如Kiko Sejio所说。
Integer和BigInteger之间的区别在于大小:
也许这对任何登陆这里的人都有帮助:我刚刚经历过同样的问题,而在我的情况下,我在外键约束之前的外键列上设置了一个(复合)唯一约束。我通过在“外国”声明之后放置“独特”声明来解决问题。
作品:
$table->foreign('step_id')->references('id')->on('steps')->onDelete('cascade');
$table->unique(['step_id','lang']);
不起作用:
$table->unique(['step_id','lang']);
$table->foreign('step_id')->references('id')->on('steps')->onDelete('cascade');
我得到了数据类型未匹配问题的相同消息。
我使用bigIncrements()作为'id',当我用它作为外键(使用bigInteger())时,我得到了错误。
我找到了解决方案,bigIncrements()返回unsignedBigInteger。因此需要在外键中使用unsignedBigInteger()而不是bigInteger()
分享这个因为它可能会帮助别人
在您的字段上添加 - > nullable()并确保您引用的所有字段确实存在。
应该对迁移文件的创建顺序进行排序,并且外键应该具有与另一个表中的主键完全相似的属性。
请记住,引用和引用字段必须具有完全相同的数据类型。
您应该在创建“餐”时首先创建类别和用户表
要解决此问题,您应该将类别和用户的迁移文件重命名为在Meals表之前创建那些的Meals Migration文件之前的日期。
2019_04_10_050958_create_users_table
2019_04_10_051958_create_categories_table
2019_04_10_052958_create_meals_table
@JuanBonnett你的问题激发了我的答案,我在laravel上采用自动化过程而不考虑文件本身的创建时间。根据工作流程,餐桌将在表(类别)之前创建,因为我创建了模式文件(餐)在类别之前。那是我的错。
只需在外键的末尾添加->unsigned()->index()
即可
对我来说,一切都是正确的顺序,但它仍然无法正常工作。然后我通过摆弄来发现主键必须是无符号的。
//this didn't work
$table->integer('id')->unique();
$table->primary('id');
//this worked
$table->integer('id')->unsigned()->unique();
$table->primary('id');
//this worked
$table->increments('id');
就我而言,新的laravel约定导致了这个错误。
只需通过表格创建id
的简单交换就可以了。
$table->increments('id'); // ok
, 代替:
$table->bigIncrements('id'); // was the error.
已经与Laravel v5.8
合作,之前从未遇到此错误。
必须自上而下创建迁移。
首先为不属于任何人的表创建迁移。
然后为属于上一个的表创建迁移。
简化了表引擎问题的答案:
要为表设置存储引擎,请在架构构建器上设置engine属性:
Schema::create('users', function ($table) {
$table->engine = 'InnoDB';
$table->increments('id');
});
来自Laravel Docs:https://laravel.com/docs/5.2/migrations
如果您在外键定义中使用->onDelete('set null')
,请确保外键字段本身是nullable()
即
//Column definition
$table->integer('user_id')->unsigned()->index()->nullable(); //index() is optional
//...
//...
//Foreign key
$table->foreign('user_id')
->references('id')
->on('users')
->onDelete('set null');
你应该创建你的迁移,例如我希望我的users
有一个role_id
字段来自我的roles
表
我首先开始让我的角色迁移php artisan make:migration create_roles_table --create=roles
然后我的第二个用户迁移php artisan make:migration create_users_table --create=users
php artisan migration
将使用创建的文件2017_08_22_074128_create_roles_table.php和2017_08_22_134306_create_users_table的顺序执行,检查日期时间顺序,即执行顺序。
文件2017_08_22_074128_create_roles_table.php
public function up()
{
Schema::create('roles', function (Blueprint $table) {
$table->increments('id');
$table->string('name', 50);
$table->timestamps();
});
}
2017_08_22_134306 create_users_table
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->increments('id');
$table->integer('role_id')->unsigned();
$table->string('name');
$table->string('phone', 20)->unique();
$table->string('password');
$table->rememberToken();
$table->boolean('active');
$table->timestamps();
$table->foreign('role_id')->references('id')->on('roles');
});
}
在我的例子中,问题是其中一个引用的表是InnoDB,另一个是MyISAM。
MyISAM不支持外键关系。
所以,现在这两个表都是InnoDB。问题解决了。