为啥在区域表定义中未创建 state_id 字段?
Posted
技术标签:
【中文标题】为啥在区域表定义中未创建 state_id 字段?【英文标题】:Why state_id field is not create in regions table definition?为什么在区域表定义中未创建 state_id 字段? 【发布时间】:2021-12-10 06:19:30 【问题描述】:我尝试将旧数据库从 laravel 5.x 重构为 laravel 8 并拥有 2 个相关表: 数据库/迁移/2019_05_21_144910_create_states_table.php:
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
class CreateStatesTable extends Migration
/**
* Run the migrations.
*
* @return void
*/
public function up()
Schema::create('states', function(Blueprint $table)
$table->smallIncrements('id')->unsigned();
$table->string('code', 3)->unique();
$table->string('name', 50)->unique();
$table->string('slug', 55)->unique();
$table->enum('active', ['A', 'I'])->default('I')->comment(' A=>Active, I=>Inactive');
$table->index(['active','code'], 'fk_states_active_code_ixd');
$table->index(['active','slug'], 'fk_states_active_slug_ixd');
);
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
Schema::drop('states');
和数据库/迁移/2019_05_21_145001_create_regions_table.php:
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
class CreateRegionsTable extends Migration
/**
* Run the migrations.
*
* @return void
*/
public function up()
Schema::create('regions', function (Blueprint $table)
$table->smallIncrements('id')->unsigned();
$table->foreign('state_id')->references('id')->on('states')->onUpdate('RESTRICT')->onDelete('RESTRICT');
$table->string('name', 50);
$table->string('slug', 55)->unique();
$table->enum('active', ['A', 'I'])->default('I')->comment(' A=>Active, I=>Inactive');
$table->unique(['state_id', 'name']);
$table->index(['state_id', 'active'], 'fk_regions_state_id_active_ixd');
);
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
Schema::drop('regions');
运行迁移命令时出错:
php artisan migrate:fresh --seed
...
Migrating: 2019_05_21_144910_create_states_table
Migrated: 2019_05_21_144910_create_states_table (626.91ms)
Migrating: 2019_05_21_145001_create_regions_table
Illuminate\Database\QueryException
SQLSTATE[42000]: Syntax error or access violation: 1072 Key column 'state_id' doesn't exist in table (SQL: alter table `regions` add constraint `regions_state_id_foreign` foreign key (`state_id`) references `states` (`id`) on delete RESTRICT on update RESTRICT)
at vendor/laravel/framework/src/Illuminate/Database/Connection.php:703
699▕ // If an exception occurs when attempting to run a query, we'll format the error
700▕ // message to include the bindings with SQL, which will make this exception a
701▕ // lot more helpful to the developer instead of just the database's errors.
702▕ catch (Exception $e)
➜ 703▕ throw new QueryException(
704▕ $query, $this->prepareBindings($bindings), $e
705▕ );
706▕
707▕
+9 vendor frames
10 database/migrations/2019_05_21_145001_create_regions_table.php:31
Illuminate\Support\Facades\Facade::__callStatic()
+32 vendor frames
43 artisan:37
Illuminate\Foundation\Console\Kernel::handle()
在区域表中,我有区域表,但没有 state_id 字段。看起来像线
$table->foreign('state_id')->references('id')->on('states')->onUpdate('RESTRICT')->onDelete('RESTRICT');
被忽略了,我无法理解为什么?试了好几次...
更新 2: 我将 CreateRegionsTable 修改为:
Schema::create('regions', function (Blueprint $table)
$table->smallIncrements('id')->unsigned();
$table->foreignId('state_id')->constrained('states')->onUpdate('RESTRICT')->onDelete('RESTRICT');
但我遇到了其他错误:
SQLSTATE[HY000]: General error: 3780 Referencing column 'state_id' and referenced column 'id' in foreign key constraint 'regions_state_id_foreign' are incompatible. (SQL: alter table `regions` add constraint `regions_state_id_foreign` foreign key (`state_id`) references `states` (`id`) on delete RESTRICT on update RESTRICT)
在 database/migrations/2019_05_21_144910_create_states_table.php 我有:
Schema::create('states', function(Blueprint $table)
$table->smallIncrements('id')->unsigned();
我认为 foreignId 与 smallIncrements 不兼容...但哪种方法有效?
提前致谢!
【问题讨论】:
foreign
在现有列上添加约束。使用foreignId('state_id')->constrained()
创建列和外键索引。更多内容请关注docs
【参考方案1】:
$table->foreign()
方法仅将外键约束添加到现有列。你要找的方法是$table->foreignId()
所以而不是
$table->foreign('state_id')->references('id')->on('states')->onUpdate('RESTRICT')->onDelete('RESTRICT');
在您的区域表迁移中,您应该这样做
$table->foreignId('state_id')->constrained('states')->onUpdate('RESTRICT')->onDelete('RESTRICT');
documentation
【讨论】:
请看更新2 抱歉回复晚了。$table->foreignId('state_id')
方法默认添加一个 bigInteger 数据类型列,而 $table->smallIncrements()
添加一个 smallInteger 数据类型列。您不能将外键约束添加到两个不同的数据类型列。您可以将 states 表的 id 列更改为 bigIncrements()
或在您的区域表中,首先为 state_id 创建一个 smallInteger() 列,然后为其添加外键约束。
请注意 smallInteger 列的最大限制为 32,767。所以使用 bigIntegers 更安全以上是关于为啥在区域表定义中未创建 state_id 字段?的主要内容,如果未能解决你的问题,请参考以下文章
为啥此 setInterval 中未定义此 useRef 值?
为啥我的变量在 useEffect 中定义的其他地方在反应中未定义?