SQLSTATE[HY000]: Общая ошибка: 1005 Не удается создать таблицу `test`.`members’ (ошибка: 150 «Неправильно сформировано ограничение внешнего ключа»)

#mysql #database #laravel #eloquent #database-migration

#mysql #База данных #laravel #красноречивый #база данных-миграция

Вопрос:

Я использую свои миграции в Laravel для создания связей между таблицами, и у меня есть 4 таблицы: users, members, member_skills и skills. У меня есть следующий код для таблицы users:

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

таблица членов:

 public function up()
{
    Schema::create('members', function (Blueprint $table) {
        $table->id();
        $table->timestamps();
        $table->string('name');
        $table->string('status');
        $table->date('date')->nullable();
        $table->text('project')->nullable();
        $table->date('start')->nullable();
        $table->foreign('name')->references('name')->on('users');
    });
}
 

таблица member_skills:

 public function up()
{
    Schema::create('member_skills', function (Blueprint $table) {
        $table->id();
        $table->timestamps();
        $table->string('name');
        $table->string('skill');
        $table->foreign('name')->references('name')->on('members');
    });
}
 

и таблица навыков:

 public function up()
{
    Schema::create('skills', function (Blueprint $table) {
        $table->id();
        $table->timestamps();
        $table->string('skill');
        $table->text('description');
        $table->foreign('skill')->references('skill')->on('member_skills');
    });
}
 

Однако выполнение моих миграций приводит к (errno: 150 "Foreign key constraint is incorrectly formed") . Я прочитал, что изменение порядка миграции должно устранить проблему, поэтому я расположил 4 таблицы для переноса в порядке users, members, member_skills и skills, но я все еще получаю ту же ошибку. Есть ли что-нибудь еще, что я делаю неправильно?

Комментарии:

1. Я думаю, вам не следует использовать имя или навык в качестве ссылок на внешний ключ, поскольку эти объекты не уникальны.

Ответ №1:

Вот правильный способ сделать это

 public function up()
{
   Schema::create('members', function (Blueprint $table) {
      ...
      $table->unsignedBigInteger('user_id');
      $table->foreign('user_id')->references('id')->on('users');
   });
}

public function up()
{
   Schema::create('member_skills', function (Blueprint $table) {
      ...
      $table->unsignedBigInteger('member_id');
      $table->foreign('member_id')->references('id')->on('members');
   });
}

public function up()
{
   Schema::create('skills', function (Blueprint $table) {
      ...
      $table->unsignedBigInteger('member_skill_id');
      $table->foreign('member_skill_id')->references('id')->on('member_skills');
   });
}
 

подробнее: https://laravel.com/docs/8.x/migrations#ограничения внешнего ключа

Ответ №2:

Вам следует попробовать использовать идентификатор таблицы-члена в качестве внешнего ключа, а не имя в схеме member_skills

     public function up()
    {
        Schema::create('member_skills', function (Blueprint $table) {
            $table->id();
            $table->timestamps();
            $table->string('member_id');
            $table->string('skill');
            $table->foreign('member_id')->references('id')->on('members');
        });
    }
 

Вы получаете эту ошибку, потому что пытаетесь ссылаться на name в таблице member, которая уже является внешним ключом к таблице users.

Вы можете получить доступ к имени участника через внешний ключ id в вашем блейде.