如何在 Laravel 迁移中使用多个数据库设置外键约束
Posted
技术标签:
【中文标题】如何在 Laravel 迁移中使用多个数据库设置外键约束【英文标题】:How do you set Foreign Key Constraint in Laravel Migration using Multiple Databases 【发布时间】:2021-12-05 21:33:09 【问题描述】:我目前正在处理一个需要使用多个数据库的项目。 在我的 .env 文件中,我有以下数据库变量:
DB_CONNECTION=mysql
DB_ONE_NAME=db1
DB_CONNECTION_TWO=mysql2
DB_TWO_NAME=db2
在我的 config/database.php 文件中,我有以下参考:
'mysql' => [
'driver' => 'mysql',
'url' => env('DATABASE_URL'),
'host' => env('DB_HOST', '127.0.0.1'),
'port' => env('DB_PORT', '3306'),
'database' => env('DB_ONE_NAME', 'db1'),
'username' => env('DB_USERNAME', 'user'),
'password' => env('DB_PASSWORD', 'root'),
'unix_socket' => env('DB_SOCKET', ''),
'charset' => 'utf8',
'collation' => 'utf8_general_ci',
'prefix' => '',
'prefix_indexes' => true,
'strict' => true,
'engine' => 'InnoDB',
'options' => extension_loaded('pdo_mysql') ? array_filter([
PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'),
]) : [],
],
'mysql2' => [
'driver' => 'mysql',
'url' => env('DATABASE_URL'),
'host' => env('DB_HOST', '127.0.0.1'),
'port' => env('DB_PORT', '3306'),
'database' => env('DB_TWO_NAME', 'db2'),
'username' => env('DB_USERNAME', 'user'),
'password' => env('DB_PASSWORD', 'root'),
'unix_socket' => env('DB_SOCKET', ''),
'charset' => 'utf8',
'collation' => 'utf8_general_ci',
'prefix' => '',
'prefix_indexes' => true,
'strict' => true,
'engine' => 'InnoDB',
'options' => extension_loaded('pdo_mysql') ? array_filter([
PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'),
]) : [],
],
在我的第一个迁移文件中,我有这个:
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateUsersTable extends Migration
public function up()
Schema::connection('mysql')->create('users', function (Blueprint $table)
$table->id();
$table->string('name');
$table->string('email')->unique();
$table->string('username')->unique();
$table->timestamps();
$table->index('id');
);
public function down()
Schema::connection('mysql')->dropIfExists('users');
在第二个迁移表中我有这个:
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateProjectsTable extends Migration
public function up()
Schema::connection('mysql2')->create('projects', function (Blueprint $table)
$table->id();
$table->foreignId('user_id')->nullable()->constrained('mysql.users')->onDelete('set null');
$table->string('name')->unique();
$table->timestamps();
$table->index(['id', 'user_id']);
);
public function down()
Schema::connection('mysql2')->dropIfExists('projects');
我做错了什么? 我检查了任何重复的文件,但找不到任何错误。
同样,我最近在我的机器上将 PHP 和 MYSQL 都升级到了它们的最新版本。在 Laravel 项目上工作所需的所有扩展都已正确安装。
但是,我仍然收到此错误:
SQLSTATE[HY000]: General error: 1005 Can't create table `db2`.`projects` (errno: 150 "Foreign key constraint is incorrectly formed") (SQL: alter table `projects` add constraint `projects_user_id_foreign` foreign key (`user_id`) references `mysql`.`users` (`id`) on delete set null)
另外,当我运行这个命令时,
php artisan migrate --pretend
或者
php artisan migrate
我仍然遇到同样的错误。
我也试过用这个:
$table->unsignedBigInteger('user_id')->nullable();
$table->foreign('user_id')->references('id')->on('mysql.users')->onDelete('set null');
但没有任何效果。 还有其他方法可以解决这个问题吗? 如果有,请给我建议。 感谢您的宝贵时间。
【问题讨论】:
您是否可以检查两个数据库是否使用相同的 ENGINE 和 CHARSET 创建?? 是的。从我发布的 config/database.php 中可以看出,他们使用的是 ENGINE 和 CHARSET。 【参考方案1】:所以在用不同类型的方法进行了大约 14 小时的测试后,我最终得到了我所谓的“你应该知道 hack”哈哈 ?
我在迁移表中使用第二个数据库连接名称,而不是使用数据库名称。
我在外键上使用连接名称的初始代码:
Schema::connection('mysql2')->create('projects', function (Blueprint $table)
$table->id();
$table->foreignId('user_id')->nullable()->constrained('mysql.users')->onDelete('set null');
$table->string('name')->unique();
$table->timestamps();
$table->index(['id', 'user_id']);
);
现在有效!使用数据库名称而不是外键上的连接名称:
Schema::connection('mysql2')->create('projects', function (Blueprint $table)
$table->id();
**$table->foreignId('user_id')->nullable()->constrained('db1.users')->onDelete('set null');**
$table->string('name')->unique();
$table->timestamps();
$table->index(['id', 'user_id']);
);
所以,第二个选项工作正常。 我希望这对某人也有帮助!!!
【讨论】:
以上是关于如何在 Laravel 迁移中使用多个数据库设置外键约束的主要内容,如果未能解决你的问题,请参考以下文章