laravel - 如何将列类型从整数更改为大整数,而其他表在 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();
});
}
解决方案
要将category_id
int 更改为 bigint,您需要:
删除列上的外键
category_id
:$table->dropForeign('admin_campaigns_category_id_foreign');
将列更改
category_id
为 bigint:$table->bigInteger('category_id')->change();
在能够重新建立外键之前,您还需要将
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();
在上面的迁移中到处都是。
这样做的原因是数字主键可能永远不会设置为负值,尤其是在将其用作自动增量列时。
通过将列设置为integer
orbigInteger
类型,您可以将最大可分配值分别限制为 2,147,483,647 或 2 63unsignedInteger
-1,而在使用or类型时,您可以保存两倍高的值,而unsignedBigInteger
所需的存储量相同(4/8 字节)。
在大多数情况下,这两个范围都很高,以至于您可能永远不会注意到差异,但这基本上是一种资源浪费。我曾经在一个非常繁忙的应用程序的用户表中看到一个整数 id 超过了最大范围,这并不漂亮。基本上,在 MySQL 中,整个数据库完全停止工作。
推荐阅读
- python - DJANGO (Python) 中 question_id 和 question.id 的区别
- ssl - Nginx:来自不同crt文件的客户端证书认证
- python - CODECADEMY avg = get_class_average(students),我想明白这个,谁能给我解释一下?
- widget - TwoLineAvatarIconListItem 调整大小
- xamarin.forms - 4.6.0847、文件和 UWP 中的 Xamarin.Forms MediaElement
- scala - Scala 如何在列表中的字符串中添加逗号?
- react-native - 如何防止键盘显示时由于“justify-content:center”导致状态栏重叠?
- javascript - 语法错误:Illegal Break Statement on using next in middleware to pass to other middleware
- typescript - 推理问题:“......在其自己的初始化程序中直接或间接引用”
- r - Titling a Histogram based on the Column Name