SlideShare une entreprise Scribd logo
1  sur  15
Multitenant Applications con GeneXus Federico Azzato, Equipo de Desarrollo fazzato@artech.com.uy
¿Que es una aplicación Multitenant? Aplicación diseñada para soportar múltiples clientes Compartir recursos de instalación Reducir costos Ej: GXportal, GXserver, Wiki, Blog, etc
¿Cómo se diseña una aplicación Multitenant? El principal problema está en los datos No hay UNA respuesta Hay varias técnicas que hacen que la aplicación sea multitenant
¿Cómo se diseña una aplicación Multitenant? Separated DB SeparatedSchema SharedSchema
Separated DB Enfoque más simple Se comparte la instalación y los programas instalados Facilita backups individuales Aumentan costos de mantenimiento Apropiada para un número reducido de tenants
SeparatedSchema Enfoque relativamente simple Cada tenant tiene sus tablas en su propio esquema en la misma DB CREATE SCHEMATenantNSchemaAUTHORIZATION TenantN ALTER USERTenantNWITH DEFAULT_SCHEMA = TenantNSchema Aumenta complejidad de administración de datos Apropiada para un número reducido de tablas (<100)
SharedSchema Los tenants comparten las tablas de la base de datos Cada tenant tiene su ID, y las consultas filtran los registros por ese ID SELECT * FROM Customer WHERETenantId = @TenantId Aumenta el costo de desarrollo ¿Qué sucede si me olvido de filtrar por TenantId? Mayor escalabilidad
¿Cuál es la mejor? Cada una tiene sus ventajas y desventajas Cada una es la más apropiada en determinado contexto
¿Quién lo dijo? “… La implementación sharedschema en 3 pasos es una roca!” @FedeAzzato Encontramos una solución para agregar el TenantId en todas las tablas, con cero impacto en tiempo de desarrollo Los programas generados no cambian en nada
Usando SQL Views y Triggers Los programas generados no se enteran que existe un campo TenantId Los SELECT, INSERT, UPDATEy DELETE se hacen contra las vistas Lo único que cambia es el CreateDB, y el string de conexión, para tener un usuario de DB para cada Tenant
Prueba de Concepto Definimos las siguientes transacciones: Customer, Product, Invoice El precio del producto varía en función del tiempo Creamos una DB singletenant, y otra con varios tenants Cargamos en cada tenant: 2000 clientes, 500 productos, 6000 facturas
Prueba de concepto TopCustomers { TopCustomersByYearinput&i = 0 to 3     {         &Year = Year(Today()) - &i Year = &Year CustomersorderCustomerName         { Customer whereSum(InvoiceTotal, Year(InvoiceDate) = &Year) > 0             { CustomerId CustomerName YearTotal = Sum(InvoiceTotal, Year(InvoiceDate) = &Year) CustomerTotalBought             }         }     } }
Prueba de concepto SELECT T1.[CustomerId], T1.[CustomerName], COALESCE( T2.[CustomerTotalBought], 0) AS CustomerTotalBought, COALESCE( COALESCE( T3.[CustomerTotalBought], 0), 0) AS CustomerTotalBought FROM (([Customer] T1 WITH (NOLOCK) LEFT JOIN(SELECT SUM(COALESCE( T5.[InvoiceTotal], 0)) AS CustomerTotalBought, T4.[CustomerId] FROM ([Invoice] T4 WITH (NOLOCK) LEFT JOIN(SELECT SUM(COALESCE( T7.[InvoiceLineTotal], 0)) AS InvoiceTotal, T6.[InvoiceId] FROM ([InvoiceLines] T6 WITH (NOLOCK) INNER JOIN(SELECT T8.[InvoiceLineQuantity] * CAST(COALESCE( T9.[ProductPriceValue], 0) AS decimal( 14, 5)) AS InvoiceLineTotal, T8.[InvoiceId], T8.[ProductId] FROM ([InvoiceLines] T8 WITH (NOLOCK) LEFT JOIN(SELECT T10.[ProductPriceValue], T10.[ProductId], T12.[InvoiceId], T10.[ProductPriceDate], T11.[GXC3] AS GXC3, T13.[InvoiceDate] FROM ((([ProductPrices] T10 WITH (NOLOCK) INNER JOIN [InvoiceLines] T12 WITH (NOLOCK) ON T12.[ProductId] = T10.[ProductId]) LEFT JOIN(SELECT MAX(T14.[ProductPriceDate]) AS GXC3, T14.[ProductId], T15.[InvoiceId] FROM (([ProductPrices] T14 WITH (NOLOCK) INNER JOIN [InvoiceLines] T15 WITH (NOLOCK) ON T15.[ProductId] = T14.[ProductId]) INNER JOIN [Invoice] T16 WITH (NOLOCK) ON T16.[InvoiceId] = T15.[InvoiceId]) WHERE T14.[ProductPriceDate] <= T16.[InvoiceDate] GROUP BY T14.[ProductId], T15.[InvoiceId] ) T11 ON T11.[ProductId] = T10.[ProductId] AND T11.[InvoiceId] = T12.[InvoiceId]) INNER JOIN [Invoice] T13 WITH (NOLOCK) ON T13.[InvoiceId] = T12.[InvoiceId]) WHERE (T10.[ProductPriceDate] = T11.[GXC3]) AND(T10.[ProductPriceDate] <= T13.[InvoiceDate]) ) T9 ON T9.[ProductId] = T8.[ProductId] AND T9.[InvoiceId] = T8.[InvoiceId]) ) T7 ON T7.[InvoiceId] = T6.[InvoiceId] AND T7.[ProductId] = T6.[ProductId]) GROUP BY T6.[InvoiceId] ) T5 ON T5.[InvoiceId] = T4.[InvoiceId]) GROUP BY T4.[CustomerId]) T2 ON T2.[CustomerId] = T1.[CustomerId]) LEFT JOIN(SELECT SUM(COALESCE( T5.[InvoiceTotal], 0)) AS CustomerTotalBought, T4.[CustomerId] FROM ([Invoice] T4 WITH (NOLOCK) LEFT JOIN(SELECT SUM(COALESCE( T7.[InvoiceLineTotal], 0)) AS InvoiceTotal, T6.[InvoiceId] FROM ([InvoiceLines] T6 WITH (NOLOCK) INNER JOIN(SELECT T8.[InvoiceLineQuantity] * CAST(COALESCE( T9.[ProductPriceValue], 0) AS decimal( 14, 5)) AS InvoiceLineTotal, T8.[InvoiceId], T8.[ProductId] FROM ([InvoiceLines] T8 WITH (NOLOCK) LEFT JOIN(SELECT T10.[ProductPriceValue], T10.[ProductId], T12.[InvoiceId], T10.[ProductPriceDate], T11.[GXC3] AS GXC3, T13.[InvoiceDate] FROM ((([ProductPrices] T10 WITH (NOLOCK) INNER JOIN [InvoiceLines] T12 WITH (NOLOCK) ON T12.[ProductId] = T10.[ProductId]) LEFT JOIN(SELECT MAX(T14.[ProductPriceDate]) AS GXC3, T14.[ProductId], T15.[InvoiceId] FROM (([ProductPrices] T14 WITH (NOLOCK) INNER JOIN [InvoiceLines] T15 WITH (NOLOCK) ON T15.[ProductId] = T14.[ProductId]) INNER JOIN [Invoice] T16 WITH (NOLOCK) ON T16.[InvoiceId] = T15.[InvoiceId]) WHERE T14.[ProductPriceDate] <= T16.[InvoiceDate] GROUP BY T14.[ProductId], T15.[InvoiceId] ) T11 ON T11.[ProductId] = T10.[ProductId] AND T11.[InvoiceId] = T12.[InvoiceId]) INNER JOIN [Invoice] T13 WITH (NOLOCK) ON T13.[InvoiceId] = T12.[InvoiceId]) WHERE (T10.[ProductPriceDate] = T11.[GXC3]) AND(T10.[ProductPriceDate] <= T13.[InvoiceDate]) ) T9 ON T9.[ProductId] = T8.[ProductId] AND T9.[InvoiceId] = T8.[InvoiceId]) ) T7 ON T7.[InvoiceId] = T6.[InvoiceId] AND T7.[ProductId] = T6.[ProductId]) GROUP BY T6.[InvoiceId] ) T5 ON T5.[InvoiceId] = T4.[InvoiceId]) WHERE YEAR(T4.[InvoiceDate]) = @YearGROUP BY T4.[CustomerId] ) T3 ON T3.[CustomerId] = T1.[CustomerId]) WHERE COALESCE( COALESCE( T3.[CustomerTotalBought], 0), 0) > 0 ORDER BY T1.[CustomerName]
Conclusión Seguimos investigando Eventualmente vamos a tener las 3 Si tienen ideas o experiencia, queremos escucharlas
¡Muchas Gracias! Federico Azzato, GeneXus Development fazzato@artech.com.uy @FedeAzzato

Contenu connexe

Similaire à Multitenant Apps con GeneXus

Programación con C/AL para Microsoft Business Solutions Navision
Programación con C/AL para Microsoft Business Solutions NavisionProgramación con C/AL para Microsoft Business Solutions Navision
Programación con C/AL para Microsoft Business Solutions Navisionpabloesp
 
Ud 7 la función de aprovisionamiento
Ud 7 la función de aprovisionamientoUd 7 la función de aprovisionamiento
Ud 7 la función de aprovisionamientomajori18
 
Contable_Financiero_I.pptx
Contable_Financiero_I.pptxContable_Financiero_I.pptx
Contable_Financiero_I.pptxRonnyMonge4
 
Qlik Sense dashboard. Chapter 2. Advanced Training
Qlik Sense dashboard. Chapter 2. Advanced TrainingQlik Sense dashboard. Chapter 2. Advanced Training
Qlik Sense dashboard. Chapter 2. Advanced TrainingMind Analytics
 
7090112 Clase Transact Sql Server
7090112 Clase Transact Sql Server7090112 Clase Transact Sql Server
7090112 Clase Transact Sql ServerCorfapo
 
7.1. procedimientos almacenados
7.1.  procedimientos almacenados7.1.  procedimientos almacenados
7.1. procedimientos almacenadosJorge Luis Lopez M
 
Configuracion y administracion del espacio en disco
 Configuracion y administracion del espacio en disco Configuracion y administracion del espacio en disco
Configuracion y administracion del espacio en discoYael_21
 
Tarea 6 consultas en neptuno access
Tarea 6 consultas en neptuno accessTarea 6 consultas en neptuno access
Tarea 6 consultas en neptuno accessmadnesshobbit
 
Proyecto Base de Datos I
Proyecto Base de Datos IProyecto Base de Datos I
Proyecto Base de Datos IMarcia Ramos
 
Programación de Base de Datos - Unidad II: Aplicaciones con Arquitectura Clie...
Programación de Base de Datos - Unidad II: Aplicaciones con Arquitectura Clie...Programación de Base de Datos - Unidad II: Aplicaciones con Arquitectura Clie...
Programación de Base de Datos - Unidad II: Aplicaciones con Arquitectura Clie...José Antonio Sandoval Acosta
 
Producción 2do.bimestre-oct 2011-feb 2012
Producción 2do.bimestre-oct 2011-feb 2012Producción 2do.bimestre-oct 2011-feb 2012
Producción 2do.bimestre-oct 2011-feb 2012Videoconferencias UTPL
 
El costeo TDABC en los Servicios de Salud
El costeo TDABC en los Servicios de SaludEl costeo TDABC en los Servicios de Salud
El costeo TDABC en los Servicios de SaludNELSON SALDIAS SEGUEL
 

Similaire à Multitenant Apps con GeneXus (20)

Valor presente y tir de fredy olmos
Valor presente y tir de fredy olmosValor presente y tir de fredy olmos
Valor presente y tir de fredy olmos
 
Programación con C/AL para Microsoft Business Solutions Navision
Programación con C/AL para Microsoft Business Solutions NavisionProgramación con C/AL para Microsoft Business Solutions Navision
Programación con C/AL para Microsoft Business Solutions Navision
 
Ud 7 la función de aprovisionamiento
Ud 7 la función de aprovisionamientoUd 7 la función de aprovisionamiento
Ud 7 la función de aprovisionamiento
 
Sql procedimientos-almacenados
Sql procedimientos-almacenadosSql procedimientos-almacenados
Sql procedimientos-almacenados
 
Contable_Financiero_I.pptx
Contable_Financiero_I.pptxContable_Financiero_I.pptx
Contable_Financiero_I.pptx
 
Access2010
Access2010Access2010
Access2010
 
Transact SQL Fundamental
Transact SQL FundamentalTransact SQL Fundamental
Transact SQL Fundamental
 
Qlik Sense dashboard. Chapter 2. Advanced Training
Qlik Sense dashboard. Chapter 2. Advanced TrainingQlik Sense dashboard. Chapter 2. Advanced Training
Qlik Sense dashboard. Chapter 2. Advanced Training
 
Sql2
Sql2Sql2
Sql2
 
Transaccion
TransaccionTransaccion
Transaccion
 
Sql Server
Sql ServerSql Server
Sql Server
 
Taller de Base de Datos - Unidad 6 SQL procedural
Taller de Base de Datos - Unidad 6 SQL proceduralTaller de Base de Datos - Unidad 6 SQL procedural
Taller de Base de Datos - Unidad 6 SQL procedural
 
7090112 Clase Transact Sql Server
7090112 Clase Transact Sql Server7090112 Clase Transact Sql Server
7090112 Clase Transact Sql Server
 
7.1. procedimientos almacenados
7.1.  procedimientos almacenados7.1.  procedimientos almacenados
7.1. procedimientos almacenados
 
Configuracion y administracion del espacio en disco
 Configuracion y administracion del espacio en disco Configuracion y administracion del espacio en disco
Configuracion y administracion del espacio en disco
 
Tarea 6 consultas en neptuno access
Tarea 6 consultas en neptuno accessTarea 6 consultas en neptuno access
Tarea 6 consultas en neptuno access
 
Proyecto Base de Datos I
Proyecto Base de Datos IProyecto Base de Datos I
Proyecto Base de Datos I
 
Programación de Base de Datos - Unidad II: Aplicaciones con Arquitectura Clie...
Programación de Base de Datos - Unidad II: Aplicaciones con Arquitectura Clie...Programación de Base de Datos - Unidad II: Aplicaciones con Arquitectura Clie...
Programación de Base de Datos - Unidad II: Aplicaciones con Arquitectura Clie...
 
Producción 2do.bimestre-oct 2011-feb 2012
Producción 2do.bimestre-oct 2011-feb 2012Producción 2do.bimestre-oct 2011-feb 2012
Producción 2do.bimestre-oct 2011-feb 2012
 
El costeo TDABC en los Servicios de Salud
El costeo TDABC en los Servicios de SaludEl costeo TDABC en los Servicios de Salud
El costeo TDABC en los Servicios de Salud
 

Plus de GeneXus

After Chatbots Yo (Ro) Bots
After Chatbots Yo (Ro) BotsAfter Chatbots Yo (Ro) Bots
After Chatbots Yo (Ro) BotsGeneXus
 
Construya las aplicaciones del futuro ¡hoy!
Construya las aplicaciones del futuro ¡hoy!Construya las aplicaciones del futuro ¡hoy!
Construya las aplicaciones del futuro ¡hoy!GeneXus
 
Live Editing in Action
Live Editing in ActionLive Editing in Action
Live Editing in ActionGeneXus
 
Experiencias en el desarrollo de aplicaciones móviles en el sector salud de M...
Experiencias en el desarrollo de aplicaciones móviles en el sector salud de M...Experiencias en el desarrollo de aplicaciones móviles en el sector salud de M...
Experiencias en el desarrollo de aplicaciones móviles en el sector salud de M...GeneXus
 
¿Pensando en implementar un sistema de gestión integral en su organización?
¿Pensando en implementar un sistema de gestión integral en su organización?¿Pensando en implementar un sistema de gestión integral en su organización?
¿Pensando en implementar un sistema de gestión integral en su organización?GeneXus
 
K2B Tools el compañero de viaje ideal hacia el futuro
K2B Tools el compañero de viaje ideal hacia el futuroK2B Tools el compañero de viaje ideal hacia el futuro
K2B Tools el compañero de viaje ideal hacia el futuroGeneXus
 
Sd y Plataformas
Sd y PlataformasSd y Plataformas
Sd y PlataformasGeneXus
 
PXTools: Nuevo generador y nuevos controles responsivos
PXTools: Nuevo generador y nuevos controles responsivosPXTools: Nuevo generador y nuevos controles responsivos
PXTools: Nuevo generador y nuevos controles responsivosGeneXus
 
APPlícate: Aplicaciones móviles para el desarrollo de la industria
APPlícate: Aplicaciones móviles para el desarrollo de la industriaAPPlícate: Aplicaciones móviles para el desarrollo de la industria
APPlícate: Aplicaciones móviles para el desarrollo de la industriaGeneXus
 
GeneXus 4 Students
GeneXus 4 StudentsGeneXus 4 Students
GeneXus 4 StudentsGeneXus
 
La importancia de ser responsive
La importancia de ser responsiveLa importancia de ser responsive
La importancia de ser responsiveGeneXus
 
K2B: El ERP nativo para el mundo GeneXus
K2B: El ERP nativo para el mundo GeneXusK2B: El ERP nativo para el mundo GeneXus
K2B: El ERP nativo para el mundo GeneXusGeneXus
 
GeneXus 15 (Salto)
GeneXus 15 (Salto)GeneXus 15 (Salto)
GeneXus 15 (Salto)GeneXus
 
GeneXus Cloud Deployment Services. El camino a la nube.
GeneXus Cloud Deployment Services. El camino a la nube.GeneXus Cloud Deployment Services. El camino a la nube.
GeneXus Cloud Deployment Services. El camino a la nube.GeneXus
 
LigaMX con GeneXus: De 0 a 1.700.000 de usuarios
LigaMX con GeneXus: De 0 a 1.700.000 de usuariosLigaMX con GeneXus: De 0 a 1.700.000 de usuarios
LigaMX con GeneXus: De 0 a 1.700.000 de usuariosGeneXus
 
Innovando con GeneXus y SAP
Innovando con GeneXus y SAPInnovando con GeneXus y SAP
Innovando con GeneXus y SAPGeneXus
 
Going mobile
Going mobileGoing mobile
Going mobileGeneXus
 
Audit+: La mejor forma de auditar KB’s GeneXus
Audit+: La mejor forma de auditar KB’s GeneXusAudit+: La mejor forma de auditar KB’s GeneXus
Audit+: La mejor forma de auditar KB’s GeneXusGeneXus
 
WW+, SD+ y Audit+: Potencie GeneXus la Suite Plus
WW+, SD+ y Audit+: Potencie GeneXus la Suite PlusWW+, SD+ y Audit+: Potencie GeneXus la Suite Plus
WW+, SD+ y Audit+: Potencie GeneXus la Suite PlusGeneXus
 
Aproveche las ventajas de la colaboración entre GeneXus y Cloud Shared Office...
Aproveche las ventajas de la colaboración entre GeneXus y Cloud Shared Office...Aproveche las ventajas de la colaboración entre GeneXus y Cloud Shared Office...
Aproveche las ventajas de la colaboración entre GeneXus y Cloud Shared Office...GeneXus
 

Plus de GeneXus (20)

After Chatbots Yo (Ro) Bots
After Chatbots Yo (Ro) BotsAfter Chatbots Yo (Ro) Bots
After Chatbots Yo (Ro) Bots
 
Construya las aplicaciones del futuro ¡hoy!
Construya las aplicaciones del futuro ¡hoy!Construya las aplicaciones del futuro ¡hoy!
Construya las aplicaciones del futuro ¡hoy!
 
Live Editing in Action
Live Editing in ActionLive Editing in Action
Live Editing in Action
 
Experiencias en el desarrollo de aplicaciones móviles en el sector salud de M...
Experiencias en el desarrollo de aplicaciones móviles en el sector salud de M...Experiencias en el desarrollo de aplicaciones móviles en el sector salud de M...
Experiencias en el desarrollo de aplicaciones móviles en el sector salud de M...
 
¿Pensando en implementar un sistema de gestión integral en su organización?
¿Pensando en implementar un sistema de gestión integral en su organización?¿Pensando en implementar un sistema de gestión integral en su organización?
¿Pensando en implementar un sistema de gestión integral en su organización?
 
K2B Tools el compañero de viaje ideal hacia el futuro
K2B Tools el compañero de viaje ideal hacia el futuroK2B Tools el compañero de viaje ideal hacia el futuro
K2B Tools el compañero de viaje ideal hacia el futuro
 
Sd y Plataformas
Sd y PlataformasSd y Plataformas
Sd y Plataformas
 
PXTools: Nuevo generador y nuevos controles responsivos
PXTools: Nuevo generador y nuevos controles responsivosPXTools: Nuevo generador y nuevos controles responsivos
PXTools: Nuevo generador y nuevos controles responsivos
 
APPlícate: Aplicaciones móviles para el desarrollo de la industria
APPlícate: Aplicaciones móviles para el desarrollo de la industriaAPPlícate: Aplicaciones móviles para el desarrollo de la industria
APPlícate: Aplicaciones móviles para el desarrollo de la industria
 
GeneXus 4 Students
GeneXus 4 StudentsGeneXus 4 Students
GeneXus 4 Students
 
La importancia de ser responsive
La importancia de ser responsiveLa importancia de ser responsive
La importancia de ser responsive
 
K2B: El ERP nativo para el mundo GeneXus
K2B: El ERP nativo para el mundo GeneXusK2B: El ERP nativo para el mundo GeneXus
K2B: El ERP nativo para el mundo GeneXus
 
GeneXus 15 (Salto)
GeneXus 15 (Salto)GeneXus 15 (Salto)
GeneXus 15 (Salto)
 
GeneXus Cloud Deployment Services. El camino a la nube.
GeneXus Cloud Deployment Services. El camino a la nube.GeneXus Cloud Deployment Services. El camino a la nube.
GeneXus Cloud Deployment Services. El camino a la nube.
 
LigaMX con GeneXus: De 0 a 1.700.000 de usuarios
LigaMX con GeneXus: De 0 a 1.700.000 de usuariosLigaMX con GeneXus: De 0 a 1.700.000 de usuarios
LigaMX con GeneXus: De 0 a 1.700.000 de usuarios
 
Innovando con GeneXus y SAP
Innovando con GeneXus y SAPInnovando con GeneXus y SAP
Innovando con GeneXus y SAP
 
Going mobile
Going mobileGoing mobile
Going mobile
 
Audit+: La mejor forma de auditar KB’s GeneXus
Audit+: La mejor forma de auditar KB’s GeneXusAudit+: La mejor forma de auditar KB’s GeneXus
Audit+: La mejor forma de auditar KB’s GeneXus
 
WW+, SD+ y Audit+: Potencie GeneXus la Suite Plus
WW+, SD+ y Audit+: Potencie GeneXus la Suite PlusWW+, SD+ y Audit+: Potencie GeneXus la Suite Plus
WW+, SD+ y Audit+: Potencie GeneXus la Suite Plus
 
Aproveche las ventajas de la colaboración entre GeneXus y Cloud Shared Office...
Aproveche las ventajas de la colaboración entre GeneXus y Cloud Shared Office...Aproveche las ventajas de la colaboración entre GeneXus y Cloud Shared Office...
Aproveche las ventajas de la colaboración entre GeneXus y Cloud Shared Office...
 

Multitenant Apps con GeneXus

  • 1. Multitenant Applications con GeneXus Federico Azzato, Equipo de Desarrollo fazzato@artech.com.uy
  • 2. ¿Que es una aplicación Multitenant? Aplicación diseñada para soportar múltiples clientes Compartir recursos de instalación Reducir costos Ej: GXportal, GXserver, Wiki, Blog, etc
  • 3. ¿Cómo se diseña una aplicación Multitenant? El principal problema está en los datos No hay UNA respuesta Hay varias técnicas que hacen que la aplicación sea multitenant
  • 4. ¿Cómo se diseña una aplicación Multitenant? Separated DB SeparatedSchema SharedSchema
  • 5. Separated DB Enfoque más simple Se comparte la instalación y los programas instalados Facilita backups individuales Aumentan costos de mantenimiento Apropiada para un número reducido de tenants
  • 6. SeparatedSchema Enfoque relativamente simple Cada tenant tiene sus tablas en su propio esquema en la misma DB CREATE SCHEMATenantNSchemaAUTHORIZATION TenantN ALTER USERTenantNWITH DEFAULT_SCHEMA = TenantNSchema Aumenta complejidad de administración de datos Apropiada para un número reducido de tablas (<100)
  • 7. SharedSchema Los tenants comparten las tablas de la base de datos Cada tenant tiene su ID, y las consultas filtran los registros por ese ID SELECT * FROM Customer WHERETenantId = @TenantId Aumenta el costo de desarrollo ¿Qué sucede si me olvido de filtrar por TenantId? Mayor escalabilidad
  • 8. ¿Cuál es la mejor? Cada una tiene sus ventajas y desventajas Cada una es la más apropiada en determinado contexto
  • 9. ¿Quién lo dijo? “… La implementación sharedschema en 3 pasos es una roca!” @FedeAzzato Encontramos una solución para agregar el TenantId en todas las tablas, con cero impacto en tiempo de desarrollo Los programas generados no cambian en nada
  • 10. Usando SQL Views y Triggers Los programas generados no se enteran que existe un campo TenantId Los SELECT, INSERT, UPDATEy DELETE se hacen contra las vistas Lo único que cambia es el CreateDB, y el string de conexión, para tener un usuario de DB para cada Tenant
  • 11. Prueba de Concepto Definimos las siguientes transacciones: Customer, Product, Invoice El precio del producto varía en función del tiempo Creamos una DB singletenant, y otra con varios tenants Cargamos en cada tenant: 2000 clientes, 500 productos, 6000 facturas
  • 12. Prueba de concepto TopCustomers { TopCustomersByYearinput&i = 0 to 3 { &Year = Year(Today()) - &i Year = &Year CustomersorderCustomerName { Customer whereSum(InvoiceTotal, Year(InvoiceDate) = &Year) > 0 { CustomerId CustomerName YearTotal = Sum(InvoiceTotal, Year(InvoiceDate) = &Year) CustomerTotalBought } } } }
  • 13. Prueba de concepto SELECT T1.[CustomerId], T1.[CustomerName], COALESCE( T2.[CustomerTotalBought], 0) AS CustomerTotalBought, COALESCE( COALESCE( T3.[CustomerTotalBought], 0), 0) AS CustomerTotalBought FROM (([Customer] T1 WITH (NOLOCK) LEFT JOIN(SELECT SUM(COALESCE( T5.[InvoiceTotal], 0)) AS CustomerTotalBought, T4.[CustomerId] FROM ([Invoice] T4 WITH (NOLOCK) LEFT JOIN(SELECT SUM(COALESCE( T7.[InvoiceLineTotal], 0)) AS InvoiceTotal, T6.[InvoiceId] FROM ([InvoiceLines] T6 WITH (NOLOCK) INNER JOIN(SELECT T8.[InvoiceLineQuantity] * CAST(COALESCE( T9.[ProductPriceValue], 0) AS decimal( 14, 5)) AS InvoiceLineTotal, T8.[InvoiceId], T8.[ProductId] FROM ([InvoiceLines] T8 WITH (NOLOCK) LEFT JOIN(SELECT T10.[ProductPriceValue], T10.[ProductId], T12.[InvoiceId], T10.[ProductPriceDate], T11.[GXC3] AS GXC3, T13.[InvoiceDate] FROM ((([ProductPrices] T10 WITH (NOLOCK) INNER JOIN [InvoiceLines] T12 WITH (NOLOCK) ON T12.[ProductId] = T10.[ProductId]) LEFT JOIN(SELECT MAX(T14.[ProductPriceDate]) AS GXC3, T14.[ProductId], T15.[InvoiceId] FROM (([ProductPrices] T14 WITH (NOLOCK) INNER JOIN [InvoiceLines] T15 WITH (NOLOCK) ON T15.[ProductId] = T14.[ProductId]) INNER JOIN [Invoice] T16 WITH (NOLOCK) ON T16.[InvoiceId] = T15.[InvoiceId]) WHERE T14.[ProductPriceDate] <= T16.[InvoiceDate] GROUP BY T14.[ProductId], T15.[InvoiceId] ) T11 ON T11.[ProductId] = T10.[ProductId] AND T11.[InvoiceId] = T12.[InvoiceId]) INNER JOIN [Invoice] T13 WITH (NOLOCK) ON T13.[InvoiceId] = T12.[InvoiceId]) WHERE (T10.[ProductPriceDate] = T11.[GXC3]) AND(T10.[ProductPriceDate] <= T13.[InvoiceDate]) ) T9 ON T9.[ProductId] = T8.[ProductId] AND T9.[InvoiceId] = T8.[InvoiceId]) ) T7 ON T7.[InvoiceId] = T6.[InvoiceId] AND T7.[ProductId] = T6.[ProductId]) GROUP BY T6.[InvoiceId] ) T5 ON T5.[InvoiceId] = T4.[InvoiceId]) GROUP BY T4.[CustomerId]) T2 ON T2.[CustomerId] = T1.[CustomerId]) LEFT JOIN(SELECT SUM(COALESCE( T5.[InvoiceTotal], 0)) AS CustomerTotalBought, T4.[CustomerId] FROM ([Invoice] T4 WITH (NOLOCK) LEFT JOIN(SELECT SUM(COALESCE( T7.[InvoiceLineTotal], 0)) AS InvoiceTotal, T6.[InvoiceId] FROM ([InvoiceLines] T6 WITH (NOLOCK) INNER JOIN(SELECT T8.[InvoiceLineQuantity] * CAST(COALESCE( T9.[ProductPriceValue], 0) AS decimal( 14, 5)) AS InvoiceLineTotal, T8.[InvoiceId], T8.[ProductId] FROM ([InvoiceLines] T8 WITH (NOLOCK) LEFT JOIN(SELECT T10.[ProductPriceValue], T10.[ProductId], T12.[InvoiceId], T10.[ProductPriceDate], T11.[GXC3] AS GXC3, T13.[InvoiceDate] FROM ((([ProductPrices] T10 WITH (NOLOCK) INNER JOIN [InvoiceLines] T12 WITH (NOLOCK) ON T12.[ProductId] = T10.[ProductId]) LEFT JOIN(SELECT MAX(T14.[ProductPriceDate]) AS GXC3, T14.[ProductId], T15.[InvoiceId] FROM (([ProductPrices] T14 WITH (NOLOCK) INNER JOIN [InvoiceLines] T15 WITH (NOLOCK) ON T15.[ProductId] = T14.[ProductId]) INNER JOIN [Invoice] T16 WITH (NOLOCK) ON T16.[InvoiceId] = T15.[InvoiceId]) WHERE T14.[ProductPriceDate] <= T16.[InvoiceDate] GROUP BY T14.[ProductId], T15.[InvoiceId] ) T11 ON T11.[ProductId] = T10.[ProductId] AND T11.[InvoiceId] = T12.[InvoiceId]) INNER JOIN [Invoice] T13 WITH (NOLOCK) ON T13.[InvoiceId] = T12.[InvoiceId]) WHERE (T10.[ProductPriceDate] = T11.[GXC3]) AND(T10.[ProductPriceDate] <= T13.[InvoiceDate]) ) T9 ON T9.[ProductId] = T8.[ProductId] AND T9.[InvoiceId] = T8.[InvoiceId]) ) T7 ON T7.[InvoiceId] = T6.[InvoiceId] AND T7.[ProductId] = T6.[ProductId]) GROUP BY T6.[InvoiceId] ) T5 ON T5.[InvoiceId] = T4.[InvoiceId]) WHERE YEAR(T4.[InvoiceDate]) = @YearGROUP BY T4.[CustomerId] ) T3 ON T3.[CustomerId] = T1.[CustomerId]) WHERE COALESCE( COALESCE( T3.[CustomerTotalBought], 0), 0) > 0 ORDER BY T1.[CustomerName]
  • 14. Conclusión Seguimos investigando Eventualmente vamos a tener las 3 Si tienen ideas o experiencia, queremos escucharlas
  • 15. ¡Muchas Gracias! Federico Azzato, GeneXus Development fazzato@artech.com.uy @FedeAzzato

Notes de l'éditeur

  1. Una aplicación multitenant es una aplicación diseñada para soportar múltiples clientes, con el objetivo principal de compartir los recursos de hardware y software de la instalación, con el objetivo final de reducir los costos de agregar nuevos clientes.
  2. El principal problema está en la separación de datos. No queremos que un tenant vea accidentalmente los datos de otro.No existe una única forma de diseñar una aplicación multitenant. Existen 2 enfoques opuestos bien definidos, pero hay muchas variantes que también se consideran aplicaciones multitenant.Por un lado, en un extremo tenemos una solución que define una separación absoluta de los datos, almacenando los datos de cada tenant en una base de datos distinta. En este caso, como hablamos de compartir los recursos de instalación, las distintas bases de datos están hosteadas en un mismo DBMS.En el extrmo opuesto, tenemos una única base de datos, donde los programas tienen parametrizadas las consultas, para filtrar los datos según el tenant que corresponda.
  3. Entreestas variantes, hay 3 enfoques que son los más interesantes.Separated DB: Esta es la alternativa que les mencionaba recién, en la que cada tenant tiene su propia base de datos.SeparatedSchema: En este enfoque se tiene una sola base de datos para todos los tenants, pero se hace una separación de los datos de los tenants utilizando esquemas.SharedSchema: En este enfoque se tienen los datos de todos los tenants en un mismo esquema, y cada tabla tiene un campo adicional al que llamaremos TenantId, el cual se utiliza para identificar a que tenant le pertenece el registro.
  4. Tener una base de datos para cada tenant, es el enfoque más simple para implementar este tipo de soluciones. Esta solución implica compartir la instalación de los programas y recursos de hardware.El tener los datos separados en distintas bases de datos por tenant, permite la oferta de servicios premium, como por ejemplo hacer backups programados, o una cantidad variable de backups por tenant.El problema de esta solución es que escala menos que las otras. O sea, las bases de datos están separadas, pero el DBMS se comparte. Entonces el límite la cantidad de tenants soportados va a estar dado por la cantidad máxima de bases de datos abiertas que soporte el DBMS.Este tipo de soluciones puede ser requerida por clientes en ámbitos financieros, o de salud, donde la política de administración de datos no les permite compartir la base de datos con otros.
  5. Este enfoque es relativamente simple de implementar. En esta solución, cada tenant tiene sus propias tablas, separadas de las tablas de otros tenants, compartiendo la misma base de datos. La separación se realiza teniendo un esquema y un usuario en la base de datos para cada tenant.De esta forma cuando un tenant hace un “SELECT * FROM Customer”, lo que está haciendo es consultar la tabla Customer del esquema que tiene asignado su usuario de base de datos.La complejidad de administración de la base de datos aumenta, ya que ahora los backups se realizan para todos los tenants en conjunto, y es muy complejo recuperar los datos de un único tenant.Este enfoque permite acomodar una cantidad mayor de tenants por base de datos, pero es necesario que los tenants tengan un número reducido de tablas.
  6. Este enfoque utiliza una única base de datos, y un único esquema dentro de la base de datos. Cada tabla tiene una columna TenantId, en la que se indica a qué tenant le pertenece el registro.Esta solución es la que tiene un mayor impacto en el tiempo y costo de desarrollo, pero su principal beneficio es que es la solución que puede acomodar el mayor número de tenants.
  7. Cada enfoque tiene sus claras ventajas y desventajas. En determinado contexto una solución va a ser mejor que las otras, pero en otro contexto distinto no.En la gráfica vemos una comparación del costo en función del tiempo para los enfoques de datos aislados (ya sea por bases separadas, o por esquemas separados), contra el enfoque de esquema compartido.
  8. Este es un fragmento de una frase recientemente twitteada por un integrante del equipo de desarrollo.
  9. La solución que estamos investigando es la de utilizar vistas para acceder a la base de datos, filtrando en la vista los registros visibles por el tenant que ejecuta la consulta.La estructura y nombre de la vista sería igual a la tabla definida por GX.La tabla real, tendría la misma estructura definida por GX, y además el campo TenantId como parte de la PK.
  10. Tener una base de datos para cada tenant, es el enfoque más simple para implementar este tipo de soluciones. Esta solución generalmente implica compartir la instalación de los programas y recursos de hardware.El tener los datos separados en distintas bases de datos por tenant, permite la oferta de servicios premium, como por ejemplo hacer backups programados, o una cantidad variable de backups por tenant.El problema de esta solución es que escala menos que las otras. O sea, las bases de datos están separadas, pero el DBMS se comparte. Entonces el límite la cantidad de tenants soportados va a estar dado por la cantidad máxima de bases de datos abiertas que soporte el DBMS.Este tipo de soluciones puede ser requerida por clientes en ámbitos financieros, o de salud, donde la política de separación de datos no les permite compartir la base de datos con otros.