Laravel 5 Multi-Tenancy App с отдельными базами данных — пользователи имеют доступ к нескольким установкам

За последние пару лет я разработал очень настраиваемое приложение PHP / MySQL, которое используется для ряда клиентов. До этого момента я создавал новую базу данных и новую установку для каждого клиента.

Первой очевидной проблемой здесь является поддержание нескольких установок в актуальном состоянии с любыми изменениями кода; вторая проблема заключается в том, что каждая установка имеет большое количество пользователей; и для большинства клиентов; некоторые из этих пользователей одинаковы — и им нужно иметь несколько отдельных учетных записей и URL-адресов, которые нужно запомнить.

Сейчас я перевожу приложение на Laravel 5 и ищу наилучшую реализацию для мультитенантности; так что ищите маленький совет по лучшей реализации. Я раньше пользовался Laravel, но ни в коем случае не эксперт.

Это то, что я думаю о настройке.

1 Основная база данных, которая содержит таблицы для:

  1. Вся информация учетной записи пользователя
  2. Таблица контроля доступа — к каким установкам пользователи могут получить доступ; каков их уровень пользователя на этой установке.
  3. Таблица конфигурации для каждой установки — информация о подключении к базе данных, базовая конфигурация и т. Д.

Затем отдельная база данных для каждой установки, которая содержит всю информацию, необходимую для этой установки и переданную ей.

Идеальной настройкой является то, что пользователь может перейти к поддомену, т. Е. Имя_установки.appname.com; войдите в систему с их основными данными для входа и автоматически перейдите к необходимой установке; ИЛИ перейдите на appname.com, войдите в систему и выберите, к какой установке подключиться.

Мои вопросы:

  1. Это лучшая договоренность для достижения того, что я ищу.
  2. Каков наилучший метод для сохранения установки, на которую смотрит пользователь (переменная сеанса)
  3. Могу ли я определить модель между двумя базами данных — возможно, определите одно соединение как главное соединение, а затем динамически определите другое соединение, используя информацию о соединении с базой данных в главной базе данных для подключения к правильной установке. — системе часто нужно проверять информацию пользователя об уровне доступа и т. д.

Я уверен, что есть много вопросов, о которых я не задумывался; но если у кого-то есть какие-либо ссылки или рекомендации, которые могут помочь, это было бы замечательно. Впервые задаю вопрос о 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.

Предполагая, что отношения будут работать через связи; Я не понимаю, почему это не сработает; Просто нужно найти лучшее место, чтобы установить связь с арендатором.

16

Решение

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

У меня тогда было два соединения, mysql и mysql_tenant; где база данных mysql_tenant задана не заранее, а динамически.

Модель User, Installations и mappings использует соединение mysql, все остальные используют mysql_tenant

Создал код для каждой установки и использовал его в качестве имени базы данных клиентов; хранение этого кода в сеансе.

Использовал промежуточное ПО MultiTenant, чтобы управлять переключением между установками с помощью следующих ключевых линий:

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

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

Существует много всего, что нужно для создания метода переключения и т. Д., Но это суть.

4

Другие решения

Трудно ответить на большую часть вашего вопроса — так как он зависит от вашего заявления и основан на мнении.

Но один бит, на который я могу ответить, — это то, что разные модели могут иметь разные соединения с базой данных. Так что ваши 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 достаточно продвинут, чтобы у вас была возможность иметь всего одну установку вместе со стратегической базой данных с четко определенными отношениями и ключами. Редко когда-либо возникает необходимость в нескольких базах данных.

Если вы можете быть более точными в своих требованиях, я могу дать более конкретный ответ.

0
По вопросам рекламы [email protected]