Ошибка: 1826 Повторяющееся имя ограничения внешнего ключа «id»

Я создал базовую базу данных, структурированную следующим образом.

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 13.07.2024 13:54

@brombeer Хорошая идея, я только что это сделал.

David Anderson 13.07.2024 13:57

Пробовали удалить , indexName: 'id'? Или использовать уникальное имя для каждого индекса? laravel.com/docs/11.x/migrations#foreign-key-constraints

brombeer 13.07.2024 14:18

@brombeer Если я правильно понимаю, здесь нужно indexName. Разве это не тот столбец родительской таблицы, на который указывает FK model_id? Что касается изменения каждой таблицы, чтобы она имела уникальное имя индекса, это был мой главный вопрос в посте. Я бы предпочел не делать этого, насколько я знаю, «id» довольно стандартен, поэтому мне было любопытно, является ли это требованием использования FK в laravel, mysql и т. д.

David Anderson 13.07.2024 14:39

@brombeer После дальнейшего прочтения вы, конечно, были правы. Кажется, было достаточно пропустить indexName. Я не знал, что FK автоматически ссылается на первичный ключ конкретной таблицы. Теперь это имеет смысл. Спасибо!

David Anderson 13.07.2024 14:53

Я думаю, это имя индекса, который вы собираетесь создать. В размещенной мной ссылке используется indexName: 'posts_user_id' для таблиц users и posts. Похоже, они должны быть уникальными

brombeer 13.07.2024 14:54
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для разработчиков
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для разработчиков
В последние годы архитектура микросервисов приобрела популярность как способ построения масштабируемых и гибких приложений. Laravel , популярный PHP...
Как построить CRUD-приложение в Laravel
Как построить CRUD-приложение в Laravel
Laravel - это популярный PHP-фреймворк, который позволяет быстро и легко создавать веб-приложения. Одной из наиболее распространенных задач в...
Освоение PHP и управление базами данных: Создание собственной СУБД - часть II
Освоение PHP и управление базами данных: Создание собственной СУБД - часть II
В предыдущем посте мы создали функциональность вставки и чтения для нашей динамической СУБД. В этом посте мы собираемся реализовать функции обновления...
Документирование API с помощью Swagger на Springboot
Документирование API с помощью Swagger на Springboot
В предыдущей статье мы уже узнали, как создать Rest API с помощью Springboot и MySql .
Роли и разрешения пользователей без пакета Laravel 9
Роли и разрешения пользователей без пакета Laravel 9
Этот пост изначально был опубликован на techsolutionstuff.com .
Как установить LAMP Stack - Security 5/5 на виртуальную машину Azure Linux VM
Как установить LAMP Stack - Security 5/5 на виртуальную машину Azure Linux VM
В предыдущей статье мы завершили установку базы данных, для тех, кто не знает.
0
6
60
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий
->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 он сгенерировал его с соглашением по умолчанию, и тогда я смог увидеть, как это работает на стороне БД.

David Anderson 13.07.2024 22:18

Другие вопросы по теме

Я продолжаю получать эту ошибку «Невозможно получить доступ к смещению строки типа в строке» всякий раз, когда пытаюсь передать фиктивные данные в свое приложение Laravel
Laravel 11 Heroku: файл базы данных по пути [/app/database/database.sqlite] не существует
Я получаю сообщение об ошибке после установки Laravel через HERD
Проверьте, существует ли UUID в таблице A или таблице B, используя правила проверки (проверка Laravel)?
Неустранимая ошибка: вызов неопределенного метода Google\Cloud\Firestore\QuerySnapshot::count()
Ошибка интеграции Alpine.js 3.x и Chart.js: «Необработанная ошибка типа: невозможно прочитать свойства со значением null (чтение «сохранить»)»
Выбор языка для Laravel 11 с сохранением для каждого сеанса
Как избавиться от распечатки отношений?
Laravel Sanctum с множественным входом в систему
Laravel: сортировка брендов фильтров не работает, но ошибка указывает на другую функцию (которая работает)