【问题标题】:General error: 1215 Cannot add foreign key constraint, Laravel 5 & MySQL一般错误:1215 无法添加外键约束,Laravel 5 & MySQL
【发布时间】:2019-09-08 17:43:27
【问题描述】:

在一个空白的 Laravel 项目中,我想在 usersquestions 之间创建外键约束,其中 users 表将包含内置 Laravel User,但Question 将是自定义模型。

运行php artisan migrate后出现以下错误:

   Illuminate\Database\QueryException  : SQLSTATE[HY000]: General error: 1215 Cannot add foreign key constraint (SQL: alter table `questions` add constraint `questions_user_id_foreign` foreign key (`user_id`) references `users` (`id`) on delete cascade)
  at /home/artur/Exposit/EDU/PHP/lara/vendor/laravel/framework/src/Illuminate/Database/Connection.php:664
    660|         // If an exception occurs when attempting to run a query, we'll format the error
    661|         // message to include the bindings with SQL, which will make this exception a
    662|         // lot more helpful to the developer instead of just the database's errors.
    663|         catch (Exception $e) {
  > 664|             throw new QueryException(
    665|                 $query, $this->prepareBindings($bindings), $e
    666|             );
    667|         }
    668| 

这里是 laravel 生成的 create_users_table 迁移:

 Schema::create('users', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->string('name');
            $table->string('email')->unique();
            $table->timestamp('email_verified_at')->nullable();
            $table->string('password');
            $table->rememberToken();
            $table->timestamps();
        });

这是我的迁移:

Schema::create('questions', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->string('title');
            $table->string('slug')->unique();
            $table->text('body');
            $table->unsignedInteger('views')->default(0);
            $table->unsignedInteger('answers')->default(0);
            $table->integer('votes')->default(0);
            $table->unsignedInteger('best_answer_id')->nullable();
            $table->unsignedInteger('user_id');
            $table->timestamps();
        });

        Schema::table('questions', function (Blueprint $table) {
            $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
        });

我尝试将问题表创建和使用外键约束更改为两个迁移,但得到了相同的错误。 请注意,stackoverflow 上的非相关答案对我有帮助。

【问题讨论】:

    标签: php mysql laravel migration


    【解决方案1】:

    Laravel 5.8 添加了 bigIncrements 作为默认值

    所以外键字段类型不匹配。您在 User 表中看到 bigIncrements(id),在 questions 表中看到 unsigned Integer(user_id)。

    如何解决

    • 要么将原始迁移从 bigIncrements() 更改为 just
      增量()
    • 或者在你的外键列中做 unsignedBigInteger() 而不是 无符号整数()。

    【讨论】:

    • 通过使用 unsignedBigInteger 类型解决了我的问题。非常感谢!
    【解决方案2】:

    在用户表bigIncrements('id') 中创建未签名的主键。

    它的类型是大整数

    当您设置外键时,它也应该是无符号的。

    添加unsigned()函数并将类型从unsignedInteger更改为bigInteger

    例子:

     Schema::create('questions', function (Blueprint $table) {
                $table->bigIncrements('id');
                $table->string('title');
                $table->string('slug')->unique();
                $table->text('body');
                $table->unsignedInteger('views')->default(0);
                $table->unsignedInteger('answers')->default(0);
                $table->integer('votes')->default(0);
                $table->unsignedInteger('best_answer_id')->nullable();
                $table->bigInteger('user_id')->unsigned();
                $table->timestamps();
                $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
            });
    

    【讨论】:

    • 解决了我的问题。非常感谢:)
    【解决方案3】:

    主键和外键的数据类型必须相同。

    请将questions迁移更新为:

    Schema::create('questions', function (Blueprint $table) {
        $table->bigIncrements('id');
        $table->string('title');
        $table->string('slug')->unique();
        $table->text('body');
        $table->unsignedInteger('views')->default(0);
        $table->unsignedInteger('answers')->default(0);
        $table->integer('votes')->default(0);
        $table->unsignedInteger('best_answer_id')->nullable();
        $table->bigInteger('user_id')->unsigned()->nullable();
        $table->timestamps();
    });
    
    Schema::table('questions', function (Blueprint $table) {
        $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
    });
    

    如果best_answer_id 也将成为外键,则也对它执行相同操作。

    【讨论】:

      【解决方案4】:

      迁移源表的变化

      Schema::create('table_name', function (Blueprint $table) {
      $table->BigIncrements('id');
      

      Schema::create('table_name', function (Blueprint $table) {
      $table->increments('id');
      

      【讨论】:

        【解决方案5】:

        我如何为 Laravel 8 修复它: L8 中生成的所有迁移仅使用$table->id();,即 bigInteger。确保在要包含外键的第二张表上,您有 $table->unsignedBigInteger('post_id');

        先设置正确的类型:

        posts table

        Schema::create('posts', function (Blueprint $table) {
         $table->id(); //note by default in laravel 8 this is bigint
         $table->string('title')->nullable();
         $table->timestamps();
        });
        

        comments table

        Schema::create('comments', function (Blueprint $table) {
         $table->id();
         $table->string('description')->nullable();
         //foriegn key set up below
         $table->unsignedBigInteger('post_id');
         $table->foreign('post_id')->references('id')->on('posts')->onDelete('cascade');
        
        });
        

        第二次重新排序迁移文件(在运行 cmets 文件之前应该先运行帖子迁移,因为 laravel 找不到帖子的 id 来创建外键)

        2021_04_10_043454_create_posts_table -> 04/10(较早的日期将首先运行) 2021_04_14_050712_create_posts_table -> 04/14(之后的日期)

        最后, 先清除缓存php artisan cache:clear 然后运行php artisan migrate

        【讨论】:

          猜你喜欢
          • 2020-06-12
          • 2019-12-27
          • 1970-01-01
          • 2021-03-29
          • 2018-07-29
          • 2018-07-29
          • 1970-01-01
          • 2019-08-02
          • 2021-07-03
          相关资源
          最近更新 更多