php - tenant - Aplicación Laravel 5 Multi-Tenancy con bases de datos separadas: los usuarios tienen acceso a múltiples instalaciones
multi tenant php (3)
Bien, lo que terminé haciendo fue tener toda la información del usuario, los nombres de las instalaciones y las asignaciones de lo que los usuarios pueden acceder a qué instalaciones en una base de datos, y toda la información del inquilino en bases de datos separadas.
Luego tuve dos conexiones, mysql y mysql_tenant; donde la base de datos mysql_tenant no está preestablecida sino dinámica.
El modelo de usuario, instalaciones y asignaciones usa la conexión mysql, todos los demás usan mysql_tenant
Creé un código para cada instalación y lo usé como el nombre de la base de datos del inquilino; Almacenando este código en la sesión.
Usó un middleware MultiTenant, para controlar el cambio entre instalaciones usando estas líneas clave:
$tenant_id = session()->get(''tenant'');
/Config::set(''database.connections.mysql_tenant.database'', $dbname);
/DB::setDefaultConnection(''mysql_tenant'');
Hay mucho más para construir el método para cambiar, etc., pero esto es lo esencial.
Durante los últimos años, he desarrollado una aplicación PHP / MySQL muy personalizada que se usa para varios clientes. He estado creando una nueva base de datos y una nueva instalación para cada cliente hasta este punto.
El primer problema obvio aquí es mantener varias instalaciones al día con cualquier cambio de código; un segundo problema es que cada instalación tiene una gran cantidad de usuarios; y para la mayoría de los clientes; algunos de estos usuarios son iguales, y tienen que tener un número de cuentas de usuario y direcciones URL separadas para recordar.
Estoy cambiando la aplicación a Laravel 5 en este momento y estoy buscando la mejor implementación para multi-tenancy; Así que busco un pequeño consejo sobre la mejor implementación. He usado Laravel antes, pero de ninguna manera soy un experto.
Esto es lo que estoy pensando en cuanto a la configuración.
1 Base de Datos Maestra que contiene tablas para:
- Toda la información de la cuenta de usuario
- Tabla de control de acceso - a qué instalaciones pueden acceder los usuarios; cuál es su nivel de usuario en esa instalación.
- Tabla de configuración para cada instalación: información de conexión a la base de datos, configuración básica, etc.
Luego, una base de datos independiente para cada instalación que contenga toda la información que se necesita y se envía a esa instalación.
La configuración ideal es que un usuario pueda ir a un subdominio, es decir, nombre_instalación.appname.com; inicie sesión con sus datos de inicio de sesión principales y vaya automáticamente a la instalación requerida; O vaya a appname.com, inicie sesión y luego seleccione a qué instalación conectarse.
Mis preguntas son:
- ¿Es este el mejor arreglo para lograr lo que estoy buscando?
- Cuál es el mejor método para almacenar qué instalación está mirando el usuario (variable de sesión)
- ¿Puedo definir un modelo entre 2 bases de datos? Quizás defina una conexión como conexión maestra, luego defina dinámicamente otra conexión utilizando la información de conexión de la base de datos en la base de datos maestra para conectarse a la instalación correcta. - el sistema a menudo tendrá que verificar la información del usuario para el nivel de acceso, etc.
Estoy seguro de que hay muchos problemas en los que no he pensado; pero si alguien tiene algún enlace u orientación que pueda ayudar eso sería genial. ¡Es la primera vez que hago una pregunta sobre SO, pero en el pasado he encontrado una gran cantidad de ayuda para la investigación, así que gracias a la comunidad!
ACTUALIZACIÓN - Así que creo que tengo una manera de hacer que esto funcione ahora; utilizando bases de datos separadas como anteriormente; conjunto
protected $connection = ''tenant_connection''
en los modelos relativos al contenido de la base de datos específica del arrendatario.
Luego, en algún lugar de un archivo de encabezado, establezca la tenant_connection que se desea en función de una variable de sesión que se haya configurado al iniciar sesión / por subdominio.
$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.
Asumiendo que las relaciones funcionarán a través de las conexiones; No veo por qué esto no funcionaría; sólo tiene que encontrar el mejor lugar para establecer la conexión del inquilino.
Es difícil responder a la mayoría de sus preguntas, ya que es específico para su aplicación y su opinión.
Pero lo único que puedo responder es que diferentes modelos pueden tener diferentes conexiones de base de datos. Entonces, su modelo de user
usa la conexión predeterminada normal, pero sus otros modelos pueden usar otra conexión:
class Example extends Model {
protected $connection= ''second_db_connection'';
}
Luego, en tu archivo de conexión DB, tendrías algo como esto:
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 es lo suficientemente avanzado como para que pueda tener simplemente una instalación junto con una base de datos estratégica, con relaciones y claves bien definidas. Rara vez hay una necesidad de múltiples bases de datos.
Si puede ser más específico acerca de sus requisitos, puedo proporcionar una respuesta más específica.