Я создал базовую базу данных, структурированную следующим образом.
vehicle_makes (id, name, slug)
vehicle_models (id, name, slug, make_id)
vehicle_trims (id, name, slug, model_id)
При попытке создать таблицу Vehicle_trims с помощью миграции Laravel я получаю сообщение об ошибке дублирования ограничения внешнего ключа.
SQLSTATE[HY000]: General error: 1826 Duplicate foreign key constraint name 'id' (Connection: mysql, SQL: alter table `vehicle_trims` add constraint `id` foreign key (`model_id`) references `vehicle_models` (`id`) on delete cascade on update cascade)
Прочитав здесь аналогичные сообщения других пользователей, я понял, что имя FK должно быть уникальным, но эта ошибка, похоже, связана с тем, что каждая таблица имеет стандартный столбец «id».
Означает ли это, что таблицам нужен уникальный идентификатор, такой как make_id, model_id и т. д., чтобы использовать внешние ключи, а затем вместо этого ссылаться на них с помощью fk_make_id, fk_model_id и т. д.?
Миграции
автомобиль_производитель
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up(): void
{
Schema::create('vehicle_makes', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('slug');
$table->timestamps();
});
}
public function down(): void
{
Schema::dropIfExists('vehicle_makes');
}
};
модели_транспортных средств
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up(): void
{
Schema::create('vehicle_models', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('slug');
$table->foreignId('make_id')
->constrained(table: 'vehicle_makes', indexName: 'id')
->onUpdate('cascade')
->onDelete('cascade');
$table->timestamps();
});
}
public function down(): void
{
Schema::dropIfExists('vehicle_models');
}
};
Vehicle_trims
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up(): void
{
Schema::create('vehicle_trims', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('slug');
$table->year('year');
$table->foreignId('model_id')
->constrained(table: 'vehicle_models', indexName: 'id')
->onUpdate('cascade')
->onDelete('cascade');
$table->timestamps();
});
}
public function down(): void
{
Schema::dropIfExists('vehicle_trims');
}
};
@brombeer Хорошая идея, я только что это сделал.
Пробовали удалить , indexName: 'id'? Или использовать уникальное имя для каждого индекса? laravel.com/docs/11.x/migrations#foreign-key-constraints
@brombeer Если я правильно понимаю, здесь нужно indexName. Разве это не тот столбец родительской таблицы, на который указывает FK model_id? Что касается изменения каждой таблицы, чтобы она имела уникальное имя индекса, это был мой главный вопрос в посте. Я бы предпочел не делать этого, насколько я знаю, «id» довольно стандартен, поэтому мне было любопытно, является ли это требованием использования FK в laravel, mysql и т. д.
@brombeer После дальнейшего прочтения вы, конечно, были правы. Кажется, было достаточно пропустить indexName. Я не знал, что FK автоматически ссылается на первичный ключ конкретной таблицы. Теперь это имеет смысл. Спасибо!
Я думаю, это имя индекса, который вы собираетесь создать. В размещенной мной ссылке используется indexName: 'posts_user_id' для таблиц users и posts. Похоже, они должны быть уникальными






->constrained(table: 'vehicle_models', indexName: 'id')
indexName здесь — это имя индекса, а не столбца, поэтому оно должно быть уникальным, например, Vehicle_trims_model_id, но вы можете его полностью опустить, и Laravel будет использовать соглашение по умолчанию для именования индексов.
Если во внешней таблице у вас был ключ с именем, отличным от «id», вы могли бы использовать
$table->foreign('model_id')->references('not_conventional_id')->on('vehicle_models');
https://laravel.com/docs/11.x/migrations#foreign-key-constraints
Отлично, спасибо за ответ и объяснение. @brombeer был прав в комментариях, но в то время я не совсем понимал FK, чтобы это осознать. После исключения indexName он сгенерировал его с соглашением по умолчанию, и тогда я смог увидеть, как это работает на стороне БД.
Почему бы не опубликовать свои миграции?