laravel 中其他表具有外部 id 关系时,如何将列类型从整数更改为大整数?

Mis*_*Das 5 migration laravel

我试图通过添加以下内容将列(admin_campaigns 表)从整数更改为大整数:

 $table->bigInteger('category_id')->change();
Run Code Online (Sandbox Code Playgroud)

但它说,无法更改列“category_id”:在外键约束“admin_campaigns_category_id_foreign”中使用”)

我该如何解决这个问题?

admin_campaigns 表:

 public function up()
    {
        Schema::create('admin_campaigns', function (Blueprint $table) {

            $table->bigIncrements('id');

            $table->string('title',50);
            $table->integer('category_id')->unsigned();
            $table->foreign('category_id')
                ->references('id')->on('admin_campaign_categories')
                ->onDelete('cascade');

            $table->tinyInteger('is_used_multimedia')->default(1)->comment('1 = yes and 0 = no');

            $table->timestamps();


        });
    }
Run Code Online (Sandbox Code Playgroud)

新迁移:

 public function up()
    {
        Schema::table('admin_campaigns', function (Blueprint $table) {
            $table->bigInteger('category_id')->change();
        });
    }
Run Code Online (Sandbox Code Playgroud)

Lup*_*abs 8

要将category_idint 更改为 bigint,您需要:

  1. 将外键拖放到category_id列上:$table->dropForeign('admin_campaigns_category_id_foreign');

  2. 将列更改category_id为 bigint:$table->bigInteger('category_id')->change();

  3. 在能够重新建立外键之前,您admin_campaign_categories.id还需要将该列更改为 bigint:

      Schema::table('admin_campaign_categories', function (Blueprint $table) {
         $table->bigInteger('id')->change();
      });
    
    Run Code Online (Sandbox Code Playgroud)

在执行此操作之前,您显然需要对 上具有外键的所有其他表中的所有其他列执行步骤 1 和 2 admin_campaign_categories.id

因此,如果该admin_campaigns表是唯一引用的表admin_campaign_categories.id,您可以执行以下操作:

public function up()
{
    Schema::table('admin_campaigns', function (Blueprint $table) {
        $table->dropForeign('admin_campaigns_category_id_foreign');
    });

    Schema::table('admin_campaign_categories', function (Blueprint $table) {
       $table->bigInteger('id')->change();
    });

    Schema::table('admin_campaigns', function (Blueprint $table) {
        $table->bigInteger('category_id')->change();
        $table->foreign('category_id')
            ->references('id')->on('admin_campaign_categories')
            ->onDelete('cascade');
    });
}

public function down()
{
    Schema::table('admin_campaigns', function (Blueprint $table) {
        $table->dropForeign('admin_campaigns_category_id_foreign');
    });

    Schema::table('admin_campaign_categories', function (Blueprint $table) {
        $table->integer('id')->change();
    });

    Schema::table('admin_campaigns', function (Blueprint $table) {
        $table->integer('category_id')->change();
        $table->foreign('category_id')
              ->references('id')->on('admin_campaign_categories')
              ->onDelete('cascade');
    });
}
Run Code Online (Sandbox Code Playgroud)

关于主键列的一句话

我还想强调,您永远不应该对数字主键列使用有符号整数/有符号大整数类型。相反,你应该使用

$table->unsignedBigInteger('id')->change();
Run Code Online (Sandbox Code Playgroud)

到处都在迁移上面。

原因是数字主键可能永远不会设置为负值,尤其是在将其用作自动增量列时尤其如此。

通过将列设置为integerorbigInteger类型,可以将最大可分配值分别限制为 2,147,483,647 或 2 63unsignedInteger -1,而使用or时可以保存两倍高的值unsignedBigInteger,而所需的存储量相同(4/8 字节) )。

在大多数情况下,这两个范围都非常高,您可能永远不会注意到差异,但这基本上是一种资源浪费。我曾在一个非常繁忙的应用程序的用户表中看到过一次整数 id 超出了最大范围,这不太好。基本上,在 MySQL 中,整个数据库完全停止工作。