【问题标题】:Laravel 5 Multi-Tenancy App with separate databases - users have access to multiple installations具有独立数据库的 Laravel 5 多租户应用程序 - 用户可以访问多个安装
【发布时间】:2015-05-10 14:49:07
【问题描述】:

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

这里的第一个明显问题是让多个安装在任何代码更改时保持最新;第二个问题是每个安装都有大量的用户;对于大多数客户而言;其中一些用户是相同的 - 他们必须拥有多个单独的用户帐户和网址才能记住。

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

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

1 个主数据库,其中包含以下表格:

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

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

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

我的问题是:

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

我确信有很多我没有想到的问题;但如果有人有任何可能有帮助的链接或指导,那就太好了。第一次提出关于 SO 的问题,但过去在这里找到了大量的研究帮助,因此感谢社区!


更新 - 所以我想我现在有办法完成这项工作;如上所述使用单独的数据库;设置

protected $connection = 'tenant_connection'

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

然后在头文件的某处根据已在登录/子域设置的会话变量设置所需的tenant_connection。

$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.

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

【问题讨论】:

  • 只是好奇,你能得到这个完整的功能吗?如果是这样,您可以发布您的解决方案作为答案吗?我也面临同样的问题
  • 我也会喜欢...我正在寻找您为您所做的一切...
  • 我会尝试发布我现在所做的作为答案,尽管它可能没有什么意义!

标签: php laravel laravel-5 multi-tenant


【解决方案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'    => '',
        ),
    ),

【讨论】:

  • 谢谢 - 我认为这里的问题是第二个数据库连接名称需要在模型中动态定义;数据库连接文件中列出了所有可能的连接;或者第二个数据库连接的详细信息需要从主数据库动态定义 - 所以不确定其中哪一个最有效/可能。
【解决方案3】:

Laravel 5 已经足够先进了,你应该能够简单地安装一个战略数据库,并具有明确定义的关系和键。很少需要多个数据库。

如果您可以更具体地说明您的要求,我可以提供更具体的答案。

【讨论】:

  • 感谢您的回答;多个数据库的原因是双重的,首先是搜索速度 - 在某些安装中,每个表将有多达 6,000 个条目。其次,该应用程序用于注册人员进行活动工作;然后在现场检查它们——有时现场没有互联网连接,所以我需要使用本地服务器设置,在这种情况下,我只想将我需要的特定数据库脱机并导入本地服务器;然后重新在线上传。拥有一个数据库会导致问题。
  • 在我的例子中,客户要求他们的数据在他们自己的国家内,并且与其他客户完全分开。这是由于法律要求。所以肯定有分离数据库的用例。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-12-16
  • 2015-12-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-15
  • 2021-04-03
相关资源
最近更新 更多