#laravel #laravel-8 #breeze #multi-tenant #multi-database-connections
Вопрос:
Здравствуйте, не могли бы вы, пожалуйста, помочь мне сделать проект laravel мультитенантным с несколькими базами данных :
Я хочу создать базу данных пользователей, например, в моей системе есть два пользователя A и B. У меня есть главная база данных и две базы данных user_a (для пользователя A) и user_b (для пользователя B). В главной базе данных у меня есть информация обо всех пользователях. Теперь я хочу, чтобы, когда пользователь A вошел в систему, он получил доступ к базе данных user_a, а когда пользователь B вошел в систему, соединение с базой данных должно быть базой данных user_b.
Ответ №1:
- Во-Первых, В
.env
:
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=master_db
DB_USERNAME=root
DB_PASSWORD=
DB_CONNECTION_A=mysql
DB_HOST_A=127.0.0.1
DB_PORT_A=3306
DB_DATABASE_A=a_db
DB_USERNAME_A=root
DB_PASSWORD_A=
DB_CONNECTION_B=mysql
DB_HOST_B=127.0.0.1
DB_PORT_B=3306
DB_DATABASE_B=b_db
DB_USERNAME_B=root
DB_PASSWORD_B=
- В
config/database.php
:
'mysql' => [
'driver' => 'mysql',
'url' => env('DATABASE_URL'),
'host' => env('DB_HOST', '127.0.0.1'),
'port' => env('DB_PORT', '3306'),
'database' => env('DB_DATABASE', 'forge'),
'username' => env('DB_USERNAME', 'forge'),
'password' => env('DB_PASSWORD', ''),
'unix_socket' => env('DB_SOCKET', ''),
'charset' => 'utf8mb4',
'collation' => 'utf8mb4_unicode_ci',
'prefix' => '',
'prefix_indexes' => true,
'strict' => true,
'engine' => null,
'options' => extension_loaded('pdo_mysql') ? array_filter([
PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'),
]) : [],
],
'mysql_a' => [
'driver' => 'mysql',
'url' => env('DATABASE_URL'),
'host' => env('DB_HOST_A', '127.0.0.1'),
'port' => env('DB_PORT_A', '3306'),
'database' => env('DB_DATABASE_A', 'forge'),
'username' => env('DB_USERNAME_A', 'forge'),
'password' => env('DB_PASSWORD_A', ''),
'unix_socket' => env('DB_SOCKET_A', ''),
'charset' => 'utf8mb4',
'collation' => 'utf8mb4_unicode_ci',
'prefix' => '',
'prefix_indexes' => true,
'strict' => true,
'engine' => null,
'options' => extension_loaded('pdo_mysql') ? array_filter([
PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'),
]) : [],
],
'mysql_b' => [
'driver' => 'mysql',
'url' => env('DATABASE_URL'),
'host' => env('DB_HOST_B', '127.0.0.1'),
'port' => env('DB_PORT_B', '3306'),
'database' => env('DB_DATABASE_B', 'forge'),
'username' => env('DB_USERNAME_B', 'forge'),
'password' => env('DB_PASSWORD_B', ''),
'unix_socket' => env('DB_SOCKET_B', ''),
'charset' => 'utf8mb4',
'collation' => 'utf8mb4_unicode_ci',
'prefix' => '',
'prefix_indexes' => true,
'strict' => true,
'engine' => null,
'options' => extension_loaded('pdo_mysql') ? array_filter([
PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'),
]) : [],
],
- В файле миграции, если таблица пользователей существует в основной базе данных и таблица книг (например) как в базе данных A, так и в:
Schema::connection('mysql')->create('users', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('database');
$table->string('email')->unique();
$table->timestamp('email_verified_at')->nullable();
$table->string('password');
$table->rememberToken();
$table->timestamps();
});
Schema::connection('mysql_a')->create('books', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->timestamps();
});
Schema::connection('mysql_b')->create('books', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->timestamps();
});
- Теперь у вас есть три подключения к базе данных, когда вы хотите включить подключение
Model
илиDB
можете это сделать:
Для моделей:
$books = Book::on('mysql_a')->find(1);
Для запросов к базе данных:
DB::connection('mysql_b')->table('books')->get();
- Пример выбора книг в соответствии с типом пользовательской базы данных:
$user = auth()->user();
switch ($user->database) {
case 'A':
return Book::on('mysql_a')->all();
break;
case 'B':
return Book::on('mysql_b')->all();
break;
}
Примечание: не забывайте запускать php artisan config:cache
при изменении .env
файла или config/database.php