具有独立数据库的Laravel 5多租户应用程序 - 用户可以访问多个安装

2022-08-31 01:20:50

在过去的几年里,我开发了一个非常定制的PHP / MySQL应用程序,用于许多客户端。到目前为止,我一直在为每个客户端创建新数据库和新安装。

这里的第一个明显问题是通过任何代码更改使多个安装保持最新状态;第二个问题是每个安装都有大量的用户;对于大多数客户;其中一些用户是相同的 - 他们必须记住许多单独的用户帐户和URL。

我目前正在将应用程序迁移到Laravel 5,并研究多租户的最佳实现;因此,请寻找有关最佳实施的一些建议。我以前使用过Laravel,但绝不是专家。

这就是我在设置方面的想法。

1 个主数据库,用于保存以下各项的表:

  1. 所有用户帐户信息
  2. 访问控制表 - 用户可以访问哪些安装;他们在该安装上的用户级别是什么。
  3. 每个安装的配置表 - 数据库连接信息、基本配置等。

然后为每个安装创建一个单独的数据库,其中包含该安装所需的所有信息,并提交到该安装。

理想的设置是用户可以转到子域,即 installationname.appname.com;使用其主登录详细信息登录并自动转到所需的安装;或者转到 appname.com,登录,然后选择要连接到的安装。

我的问题是:

  1. 这是实现我所寻找的目标的最佳安排吗?
  2. 存储用户正在查看的安装的最佳方法是什么(会话变量)
  3. 我是否可以在 2 个数据库之间定义一个模型 - 也许将一个连接定义为主连接,然后使用 master 数据库中的数据库连接信息动态定义另一个连接以连接到正确的安装。- 系统经常需要检查用户信息的访问级别等。

我相信有很多问题我没有想到;但是,如果有人有任何可能有帮助的链接或指导,那就太好了。第一次问SO的问题,但过去在这里发现了大量的研究帮助,所以感谢社区!


更新 - 所以我认为我现在有办法做到这一点;使用如上所述的单独数据库;设置

protected $connection = 'tenant_connection'

在与租户特定的数据库内容相关的模型中。

然后,在头文件中的某个位置设置所需的tenant_connection,该变量基于已在 login/by 子域上设置的会话变量。

$tenant = Installation::where('installation', '=', $session['installation'])->first();
Config::set('database.connections.tenant_connection', array('driver' => 'mysql', 'host' => $tenant->db_hostname, 'username' => $tenant->db_username)... etc.

假设关系将跨连接工作;我不明白为什么这行不通;只需要找出设置租户连接的最佳位置。


答案 1

好吧,所以我最终所做的是将所有用户信息,安装名称和用户可以访问哪些安装的映射放在一个数据库中,以及所有租户信息放在单独的数据库中。

然后我有两个连接,mysql和mysql_tenant;其中mysql_tenant数据库不是预先设置的,而是动态的。

用户、安装和映射模型使用 mysql 连接,所有其他模型都使用mysql_tenant

为每个安装创建一个代码,并将其用作租户数据库的名称;将此代码存储在会话中。

使用中间件 MultiTenant,使用以下关键行来控制安装之间的切换:

$tenant_id = session()->get('tenant');

\Config::set('database.connections.mysql_tenant.database', $dbname);
\DB::setDefaultConnection('mysql_tenant');

对于构建切换等方法还有很多内容,但这是要点。


答案 2

很难回答您的大部分问题 - 因为它特定于您的应用程序和基于意见的问题。

但我能回答的一点是,不同的模型可以有不同的数据库连接。因此,您的模型使用正常的默认连接 - 但您的其他模型可以使用另一个连接:user

class Example extends Model {

    protected $connection= 'second_db_connection';

}

然后在数据库连接文件中 - 您将有如下内容:

return array(
    'connections' => array(
        'mysql' => array(
            'driver'    => 'mysql',
            'host'      => 'localhost',
            'database'  => 'database1',
            'username'  => 'user1',
            'password'  => 'pass1'
            'charset'   => 'utf8',
            'collation' => 'utf8_unicode_ci',
            'prefix'    => '',
        ),

        'second_db_connection' => array(
            'driver'    => 'mysql',
            'host'      => 'localhost',
            'database'  => 'database2',
            'username'  => 'user2',
            'password'  => 'pass2'
            'charset'   => 'utf8',
            'collation' => 'utf8_unicode_ci',
            'prefix'    => '',
        ),
    ),

推荐