php 迁移表中有多个外键

rta7y2nd  于 2023-04-10  发布在  PHP
关注(0)|答案(1)|浏览(111)

我在做三张table;书籍表、作家表、书籍类型表。
我试图约束books表中的3个外键作者ID、作者姓名和流派名称。
一旦我为它编写了代码,它在我的数据库中看起来很好,但laravel给了我一个错误,我感到困惑:

SQLSTATE[HY000]:一般错误:1005无法创建表test.books(错误号:150“Foreign key constraint is incorrectly formed”)(SQL:alter table books add constraint books_writer_name_foreign外键(writer_name)references writersname)on delete cascade on update cascade)

图书桌

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();
        });
    }
iqjalb3h

iqjalb3h1#

在使用数据库时,为每一列使用适当的数据类型是很重要的。在您提供的Laravel迁移代码中,列“writer_name”被定义为字符串,但它也被用作外键来引用“writers”表中的“name”列。这不是一个好的做法,因为外键应该引用具有一致数据类型和大小的列。
要解决此问题,使用字符串列作为外键可能导致数据不一致,并可能在将来导致错误。相反,您可以建议使用整数列来存储每个写入程序的唯一标识符,然后在当前表中的整数列和“写入程序”表中的相应整数列之间创建外键关系。这样,外键将引用一致的数据类型和大小,这将提高数据库的性能和可靠性。
因此最好从迁移文件中删除此行

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

相关问题