Laravel - Мультитенантность - Одна база данных, несколько таблиц

Я хочу создать мультитенантное приложение с помощью Laravel. Я использую архитектуру базы данных одна база данных, несколько таблиц клиентов.

Я хочу динамически создавать новый набор таблиц, связанных с арендатором, всякий раз, когда кто-то регистрирует новую учетную запись клиента.

Обратите внимание на следующее:

дизайн

Таблица tenants содержит все регистрации клиентов. У каждого арендатора будут выделенные столы только для них. В этом примере у каждого арендатора есть собственная выделенная таблица клиентов.

Ex:

Таблицы tenant01 будут иметь префикс tenant01. (tenant01.customer - только клиенты tenant01)

Таблицы tenant02 будут иметь префикс tenant02. (tenant02.customer - только клиенты tenant02)

Я не хочу использовать несколько баз данных, поскольку они дорогостоящие, и я не хочу использовать одну таблицу для всех клиентов, так как в системе будет много клиентов / продуктов и т. Д.

Я планирую идентифицировать клиента в процессе регистрации и установить имя клиента (или код / ​​идентификатор) в сеансе. пример: tenant440

После этого во всех классах красноречивых моделей, связанных с клиентами, я мог динамически добавлять этот префикс (например, tenant440) в имя таблицы следующим образом:

<?php

class Customer extends Eloquent {

    protected $tenant_name = //get name/code from the session. ex: tenant440

    //table name will become tenant440.'customers'
    protected $table = $tenant_name.'customers';


?>

Это правильный способ добиться этого? Как это сделать проще всего? Вы знаете какие-либо ресурсы / пакеты / библиотеки для этого?

Заранее спасибо!


person stackflow    schedule 05.08.2014    source источник


Ответы (1)


Вы можете установить имя клиента в качестве префикса в файле базы данных:

Config::set('database.connections.mysql.prefix',$tenantName); // assuming 'mysql' is the default database connection name

Рекомендую поместить внутрь фильтра

// routes.php
Route::group(array('before'=>'setTablePrefix'), function($noob)
{
    Route::resource('customers', 'CustomersController');
    Route::controller('sales', 'SalesController');
});
Route::get('/login',array('as' => 'login', 'uses' => 'UserController@getLogin'));


// filters.php
Route::filter('setTablePrefix', function($route, $request) 
{
    if (!Session::has('prefixTable'))
        App::abort(404);
    Config::set('database.connections.mysql.prefix',Session::get('prefixTable'));
});

Чтобы получить данные из всех таблиц, вам, вероятно, понадобится два запроса (или один, если вы используете Session)

$tenants = DB::table('tenants')->lists('name'); // you can set it in Session
if($tenants){
    $allCustomers = DB::table($tenants[0].'.customers');
    for ($i = 1; $i < count($tenants); $i++) { 
        $allCustomers->unionall(DB::table($tenants[$i].'.customers'));
    }
    var_dump($allCustomers->get()); 
}
person Razor    schedule 05.08.2014
comment
Привет, большое спасибо за подсказку! Могу я вас спросить: что, если есть сценарий, в котором администратору нужно просматривать всех клиентов (или продажи) во всей базе данных? Как я могу читать из всех таблиц? Например, что, если администратору нужно знать всю сумму продаж? Можно ли получить? - person stackflow; 06.08.2014