迁移表中的多个外键

问题描述 投票:0回答:1

我正在制作3张桌子;书籍表、作家表、书籍类型表。

我试图限制 books 表中的 3 个外键;作家 ID、作家姓名和流派名称。

一旦我为它编写代码,它在我的数据库中看起来很好但是 laravel 给了我一个令我困惑的错误:

SQLSTATE[HY000]: General error: 1005 Can't create table `test`.`books` (errno: 150 "Foreign key constraint is incorrectly formed") (SQL: alter table `books` add constraint `books_writer_name_foreign` 外国键(`writer_name`)在更新级联上删除级联时引用`writers`(`name`)

书桌


    public function up()
    {
        Schema::create('books', function (Blueprint $table) {
            $table->id();
            $table->string('name');

            $table->unsignedBigInteger('writer_id');
            $table->foreign('writer_id')->references('id')->
            on('writers')->onUpdate('cascade')->onDelete('cascade');

            $table->string('writer_name');
            $table->foreign('writer_name')->references('name')->
            on('writers')->onUpdate('cascade')->onDelete('cascade');

            $table->string('genre_name');
            $table->foreign('genre_name')->references('name')->
            on('book_genres')->onUpdate('cascade')->onDelete('cascade');


            $table->timestamps();
        });
    }

作家桌

    public function up()
    {
        Schema::create('writers', function (Blueprint $table) {
            $table->id();
            $table->string('name');
            $table->timestamps();
        });
    }

书籍流派表

    public function up()
    {
        Schema::create('book_genres', function (Blueprint $table) {
            $table->id();
            $table->string('name');
            $table->timestamps();
        });
    }
php laravel datatables migration laravel-8
1个回答
0
投票

使用数据库时,为每一列使用适当的数据类型很重要。在您提供的 Laravel 迁移代码中,列“writer_name”被定义为一个字符串,但它也被用作外键来引用“writers”表中的“name”列。这不是一个好的做法,因为外键应该引用具有一致数据类型和大小的列。

为了解决这个问题,使用字符串列作为外键会导致数据不一致,将来可能会出错。相反,您可以建议使用整数列为每个 writer 存储唯一标识符,然后在当前表中的整数列与“writers”表中相应的整数列之间创建外键关系。这样,外键将引用一致的数据类型和大小,从而提高数据库的性能和可靠性。

所以最好从迁移文件中删除这一行

$table->string('writer_name');
            $table->foreign('writer_name')->references('name')->
            on('writers')->onUpdate('cascade')->onDelete('cascade');
© www.soinside.com 2019 - 2024. All rights reserved.