tenant single que multi data database-design architecture database-schema multi-tenant

database-design - single - multi-tenant data architecture



¿Debo usar una configuración de base de datos única o múltiple para una aplicación multicliente? (10)

Estoy trabajando en una aplicación PHP que pretende facilitar el flujo de trabajo de la empresa y la gestión de proyectos, digamos algo como Basecamp y GoPlan .

No estoy seguro de cuál es el mejor enfoque, basado en la base de datos. ¿Debería usar una única base de datos y agregar columnas específicas del cliente a cada una de las tablas, o debería crear una base de datos para cada cliente nuevo? Un factor importante es la automatización: quiero que sea absolutamente simple crear un nuevo cliente (y tal vez abrir la posibilidad de registrarse por usted mismo).

Posibles contras que puedo pensar en usar una base de datos:

  • Falta de extensibilidad
  • Problemas de seguridad (aunque los errores no deberían estar allí en primer lugar )

¿Cuáles son sus pensamientos sobre esto? ¿Tiene alguna idea de qué solución es más probable que las compañías anteriores hayan elegido?


Cuando diseña una base de datos de múltiples usuarios, generalmente tiene tres opciones:

  1. Tener una base de datos por inquilino
  2. Tener un esquema por inquilino
  3. Haga que todos los inquilinos compartan la misma mesa (s)

La opción que elija tiene implicaciones en la escalabilidad, extensibilidad y aislamiento. Estas implicaciones han sido ampliamente discutidas en diferentes preguntas de y artículos de la base de datos.

En la práctica, cada una de las tres opciones de diseño, con suficiente esfuerzo, puede abordar las preguntas en torno a la escala, los datos que varían entre los inquilinos y el aislamiento. La decisión depende de la dimensión principal para la que está construyendo. El resumen:

  • Si está creando para la escala: haga que todos los inquilinos compartan la misma mesa (s)
  • Si está creando aislamiento: cree una base de datos por inquilino

Por ejemplo, Google y Salesforce siguen el primer patrón y hacen que sus inquilinos compartan las mismas tablas. por otro lado sigue el segundo patrón y mantiene una base de datos por inquilino. El segundo enfoque también es más común en las industrias reguladas, como la salud.

La decisión se reduce a la dimensión principal para la que optimiza el diseño de su base de datos. Este artículo sobre el diseño de su base de datos SaaS para la escala habla sobre las concesiones y proporciona un resumen en el contexto de PostgreSQL.


El siguiente screencast explica cómo se hace en salesforce.com. Usan una base de datos con una columna especial OrgId que identifica los datos de cada inquilino. Hay mucho más para eso, así que deberías ver esto. Yo iría con su enfoque.

Hay otro gran article sobre eso en MSDN. Explica en profundidad cuándo debe usar un enfoque compartido o aislado. Recuerde que tener una base de datos compartida para todos sus inquilinos tiene algunas implicaciones de seguridad importantes y si todos ellos comparten los mismos objetos DB que desee usar [seguridad a nivel de fila], dependiendo del DBMS que use (estoy seguro de que es posible en MS SQL Server y Oracle, probablemente en IBM DB2 también). Puede usar trucos como seguridad de nivel de fila en mySQL para lograr resultados similares (vistas + desencadenadores).


En el caso de las instalaciones multifuncionales, el rendimiento generalmente aumentará cuanto más recursos se administren para compartir entre los inquilinos, vea

http://en.wikipedia.org/wiki/Multitenancy

Entonces, si puede, vaya con la base de datos única. Estoy de acuerdo en que los problemas de seguridad solo se producirán debido a errores, ya que puede implementar todo el control de acceso en la aplicación. En algunas bases de datos, aún puede usar el control de acceso a la base de datos mediante el uso cuidadoso de las vistas (para que cada usuario autenticado obtenga una vista diferente).

Hay formas de proporcionar extensibilidad también. Por ejemplo, puede crear una sola tabla con atributos de extensión (codificados por inquilino, registro base e ID de atributo de extensión). O puede crear tablas de extensión por inquilino, de modo que cada inquilino tenga su propio esquema de extensión.


En mi opinión, dependerá de su base de clientes probable. Si pudiera entrar en una situación en la que sus archirrivales usaran su sistema, entonces sería mejor que tuviera bases de datos separadas. También depende de cómo el DBMS implementa las múltiples bases de datos. Si cada base de datos tiene una copia separada de la infraestructura, eso sugiere una única base de datos (o un cambio de DBMS). Si varias bases de datos pueden ser servidas por una sola copia de la infraestructura, entonces buscaría bases de datos separadas.

Piense en el respaldo de la base de datos El cliente A dice "Por favor envíeme una copia de mis datos". Mucho, mucho más fácil en una configuración de base de datos separada que si se comparte una única base de datos. Piensa en eliminar un cliente; de nuevo, mucho más fácil con bases de datos separadas.

(La parte de ''infraestructura'' es bochornosa porque hay diferencias importantes entre diferentes DBMS sobre lo que constituye una ''base de datos'' contra una ''instancia de servidor'', por ejemplo. Agregar : la pregunta está etiquetada ''mysql'', por lo que tal vez esos pensamientos no sean completamente relevante.)

Agregar : un problema más: con múltiples clientes en una única base de datos, cada consulta SQL deberá garantizar que se elijan los datos para el cliente correcto. Eso significa que el SQL va a ser más difícil de escribir y leer, y el DBMS tendrá que trabajar más duro en el procesamiento de los datos, y los índices serán más grandes, y ... Realmente iría con una base de datos separada por cliente para muchos propósitos.

Claramente, (como ejemplo) no tiene una base de datos separada por usuario; todos usamos la misma base de datos. Pero si estuviera ejecutando sistemas de contabilidad para diferentes compañías, no creo que sea aceptable (para las compañías, y posiblemente no para las personas jurídicas) compartir bases de datos.


Escucha el podcast donde Joel y Jeff hablan sobre la misma pregunta. Joel está hablando de su experiencia ofreciendo una versión alojada de su software. Señala que agregar identificadores de clientes en todo su DB complica el diseño y el código (¿está seguro de que no se olvidó accidentalmente de agregarlo a alguna cláusula WHERE?) Y complica la función de alojamiento, como las copias de respaldo específicas del cliente.

Fue en el episodio # 20 o # 21 (verifique las transcripciones para más detalles).


Normalmente agrego ClientID a todas las tablas y voy con una base de datos. Pero dado que la base de datos suele ser difícil de escalar, también permitiré ejecutar en instancias de bases de datos diferentes para algunos o todos los clientes.

De esta forma, puede tener un grupo de clientes pequeños en una base de datos y los grandes en servidores separados.

Sin embargo, un factor clave para el mantenimiento es que mantiene el esquema idéntico en todas las bases de datos. Habrá dolor de cabeza suficiente para administrar el control de versiones sin presentar esquemas específicos del cliente.


Otro punto a considerar es que puede tener la obligación legal de mantener los datos de una empresa separados de los demás.


Puede comenzar con una única base de datos y particionarla a medida que crece la aplicación. Si haces esto, hay algunas cosas que recomendaría:

1) Diseña la base de datos de forma que pueda dividirse fácilmente. Por ejemplo, si los clientes van a compartir datos, asegúrese de que los datos se repliquen fácilmente en cada base de datos.

2) Cuando solo tiene una base de datos, asegúrese de que esté respaldada en otro servidor físico. En el caso de una conmutación por error, puede revertir el tráfico a este otro servidor y aún así tener sus datos intactos.


Tener una base de datos por cliente generalmente no se escala bien. MySQL (y probablemente otras bases de datos) mantiene los recursos abiertos por tabla, esto no se presta bien a 10k + tablas en una instancia, lo que ocurriría en una situación de múltiples usuarios a gran escala.

Por supuesto, si tiene algún otro problema que causa otros problemas antes de llegar a este nivel, esto puede no ser relevante.

Además, es probable que "sharding" una aplicación multi-tenant sea lo correcto a medida que su aplicación se hace cada vez más grande.

Sin embargo, Sharding no significa una base de datos (o instancia) por inquilino, sino una por fragmento o conjunto de fragmentos, que pueden tener varios inquilinos cada uno. Necesitará descubrir los parámetros de ajuste correctos para usted, probablemente en producción (por lo tanto, probablemente deba ser bastante optimizable desde el principio)

€ No puedo garantizarlo.


  • DESARROLLO Para un desarrollo rápido, use una base de datos por cliente. Piense en lo fácil que será hacer una copia de seguridad, restaurar o eliminar los datos de un cliente. O para medir / monitorear / facturar el uso. No necesitará escribir código para hacerlo usted mismo, solo use sus primitivos de base de datos.

  • RENDIMIENTO Para el rendimiento, use una base de datos para todos. Piense en la agrupación de conexiones, la memoria compartida, el almacenamiento en caché, etc.

  • NEGOCIOS Si su plan de negocios es tener muchos clientes pequeños (piense en Hotmail) probablemente debería trabajar en una única base de datos. Y tenga todas las tareas administrativas tales como registro, borrado, migración de datos, etc. completamente automatizadas y expuestas en una interfaz amigable. Si planea tener docenas o hasta unos pocos cientos de grandes clientes, entonces puede trabajar en una base de datos por cliente y tener scripts de administración del sistema implementados que puedan ser operados por el personal de soporte al cliente.