首页 > 解决方案 > 如何将列类型从整数更改为大整数,而其他表在 laravel 中具有外部 id 关系?

问题描述

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

 $table->bigInteger('category_id')->change();

但它说,不能更改列 'category_id': used in a foreign key constraint '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();


        });
    }

新迁移:

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

标签: laravelmigration

解决方案


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

在执行此操作之前,您显然需要对所有其他表中具有外键的所有其他列执行步骤 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');
    });
}

关于主键列的一句话

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

$table->unsignedBigInteger('id')->change();

在上面的迁移中到处都是。

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

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

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


推荐阅读