是否可以在 Laravel 的不同数据库中引用外键?

Posted

技术标签:

【中文标题】是否可以在 Laravel 的不同数据库中引用外键?【英文标题】:Is it possible to reference a Foreign Key in a different database in Laravel? 【发布时间】:2015-05-11 02:02:45 【问题描述】:

我正在尝试在 Laravel 4.2 中为该模型创建模型和迁移。我所有的 Laravel 应用程序都使用同一个名为 laravelmysql 数据库。但是,我们还有另一个数据库(在同一台服务器上),名为 main_db,其中包含一个 users 表,我想将其用作我自己的 laravel_users 表中的几个外键的来源@ 987654325@数据库。

根据 Laravel 文档,我将使用以下代码指定一个外键:

$table->foreign('user_id')->references('id')->on('users');

但我相信这是假设'users' 表存在于同一个数据库中。

可以在 Laravel 中做跨数据库外键吗?我是否必须首先创建一个使用来自main_dbusers 表的模型?是否可以在app/config/database.php 中设置两个不同的数据库连接?

【问题讨论】:

【参考方案1】:

跨数据库外键实际上与 Laravel 没有太大关系。真正的问题是数据库是否支持它。 MySQL(至少在 InnoDB 中)确实支持跨多个数据库的外键约束。您只需使用点符号指定数据库:db.table

关于 Laravel 模式构建器,这应该可以工作:

$table->foreign('user_id')->references('id')->on('main_db.users');
//                                                ^^^^^^^

如果出现错误,请检查列类型是否相同。 (您不能将 varchar 引用为 int,反之亦然,键的类型必须相同)。

【讨论】:

哇哦。我喜欢它干净利落地融合在一起。非常感谢。只是为了澄清一下,然后我是否必须为每个数据库添加点符号? IE。从现在开始,我以前的所有 Laravel 模型都必须使用 laravel.xxxx...? 不客气。不,您只需指定数据库,如果它与您添加密钥的表所在的数据库不同。 你能告诉我方法references是在哪里定义的吗? Blueprint::foreign 返回Fluent,这不包含references。那么在哪里可以找到呢?! @scarface 它没有在任何地方明确定义。 Fluent 类接受所有方法调用,本质上只是在内部设置键值对。 Source @lukasgeiter 谢谢。我没有考虑过那种神奇的方法。【参考方案2】:

如果您更改数据库的名称,这将不起作用,以供将来参考。最好通过数据库定义来获取数据库的名称。

config/database.php

'auth_database' => [
    'driver' => 'mysql',
    'host' => env('DB_HOST', 'localhost'),
    'port' => env('DB_PORT', '3306'),
    'database' => env('DB_DATABASE', 'forge'),
    'username' => env('DB_USERNAME', 'forge'),
    'password' => env('DB_PASSWORD', ''),
    'charset' => 'utf8',
    'collation' => 'utf8_unicode_ci',
    'prefix' => '',
    'strict' => false,
    'engine' => null,
],

然后在你的迁移文件中:

Schema::create('role_user', function (Blueprint $table) 
    $db = DB::connection('auth_database')->getDatabaseName();

    $table->integer('role_id')->unsigned();
    $table->foreign('role_id')->references('id')->on('roles');
    $table->integer('user_id')->unsigned();
    $table->foreign('user_id')->references('id')->on(new Expression($db . '.users'));
);

【讨论】:

我改用->on(config('database.connections.mysql.database') . '.users') 这拯救了我的一天!非常感谢@travisneids【参考方案3】:

@lukasgeiter 的答案对我有用,有以下两个变化:

1- 我将两个数据库引擎都更改为 InnoDB

2- 我必须在迁移文件中将外键设置为 无符号整数,因为引用是无符号整数并且是主键。

$table->integer('user_id')->unsigned()->change();

【讨论】:

以上是关于是否可以在 Laravel 的不同数据库中引用外键?的主要内容,如果未能解决你的问题,请参考以下文章

SQL:alter table`familymembers`在laravel中添加约束`familymembers_user_id_foreign`外键(`user_id`)引用`all_users`

如何在 Laravel 迁移中创建自引用关系(外键)?

是否可以直接在 NHibernate 中设置引用的外键?

Laravel 迁移自引用外键问题

Laravel 6:违反完整性约束:1452无法添加或更新子行:外键约束失败

Laravel 迁移:创建 2 个表用户表和广告表(外键引用用户 ID)