За последние пару лет я разработал очень настраиваемое приложение PHP / MySQL, которое используется для ряда клиентов. До этого момента я создавал новую базу данных и новую установку для каждого клиента.
Первой очевидной проблемой здесь является поддержание нескольких установок в актуальном состоянии с любыми изменениями кода; вторая проблема заключается в том, что каждая установка имеет большое количество пользователей; и для большинства клиентов; некоторые из этих пользователей одинаковы — и им нужно иметь несколько отдельных учетных записей и URL-адресов, которые нужно запомнить.
Сейчас я перевожу приложение на Laravel 5 и ищу наилучшую реализацию для мультитенантности; так что ищите маленький совет по лучшей реализации. Я раньше пользовался Laravel, но ни в коем случае не эксперт.
Это то, что я думаю о настройке.
1 Основная база данных, которая содержит таблицы для:
Затем отдельная база данных для каждой установки, которая содержит всю информацию, необходимую для этой установки и переданную ей.
Идеальной настройкой является то, что пользователь может перейти к поддомену, т. Е. Имя_установки.appname.com; войдите в систему с их основными данными для входа и автоматически перейдите к необходимой установке; ИЛИ перейдите на appname.com, войдите в систему и выберите, к какой установке подключиться.
Мои вопросы:
Я уверен, что есть много вопросов, о которых я не задумывался; но если у кого-то есть какие-либо ссылки или рекомендации, которые могут помочь, это было бы замечательно. Впервые задаю вопрос о 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.
Предполагая, что отношения будут работать через связи; Я не понимаю, почему это не сработает; Просто нужно найти лучшее место, чтобы установить связь с арендатором.
Итак, в итоге я получил всю пользовательскую информацию, имена установок и сопоставления того, какие пользователи могут получить доступ к каким установкам в одной базе данных, и всю информацию об арендаторах в отдельных базах данных.
У меня тогда было два соединения, 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');
Существует много всего, что нужно для создания метода переключения и т. Д., Но это суть.
Трудно ответить на большую часть вашего вопроса — так как он зависит от вашего заявления и основан на мнении.
Но один бит, на который я могу ответить, — это то, что разные модели могут иметь разные соединения с базой данных. Так что ваши 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' => '',
),
),
Laravel 5 достаточно продвинут, чтобы у вас была возможность иметь всего одну установку вместе со стратегической базой данных с четко определенными отношениями и ключами. Редко когда-либо возникает необходимость в нескольких базах данных.
Если вы можете быть более точными в своих требованиях, я могу дать более конкретный ответ.