¿Debo usar una configuración de base de datos única o múltiple para una aplicación multi-cliente?


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, en lo que respecta a la base de datos. ¿Debo usar una única base de datos y agregar columnas específicas del cliente a cada una de las tablas, o debo crear una base de datos para cada nuevo cliente? Un factor importante es la automatización: quiero que sea muy simple crear un nuevo cliente (y tal vez abrir el posibilidad de registrarse por sí mismo).

Posibles contras Se me ocurre usar una base de datos:

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

¿Qué piensas sobre esto? ¿Tiene alguna idea de qué solución es más probable que las empresas anteriores hayan elegido?

Author: givanse, 2008-11-01

10 answers

Normalmente añado 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 haré posible que se ejecute en diferentes instancias de base de datos para algunos o todos los clientes.

De esa manera puede tener un montón de clientes pequeños en una base de datos y los grandes en servidores separados.

Un factor clave para la mantenibilidad es que mantenga el esquema idéntico en todas las bases de datos. Habrá suficiente dolor de cabeza para administrar el control de versiones sin introducción de esquemas específicos del cliente.

 37
Author: idstam,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-11-01 08:21:14

Escucha el podcast de Stackoverflow 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 ID de cliente en toda la base de datos 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 seguridad específicas del cliente.

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

 34
Author: Philipp Schmid,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-11-01 16:19:48

En mi opinión, dependerá de su base de clientes probable. Si pudiera entrar en una situación en la que los archirrivales están usando su sistema, entonces estaría mejor con bases de datos separadas. También depende de cómo múltiples bases de datos se implementan por su DBMS. Si cada base de datos tiene una copia separada de la infraestructura, entonces eso sugiere una sola base de datos (o un cambio de DBMS). Si múltiples bases de datos pueden ser servidas por una sola copia de la infraestructura, entonces iría por separado base.

Piense en la copia de seguridad 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 sola base de datos. Piense en eliminar a un cliente; de nuevo, mucho más fácil con bases de datos separadas.

(La parte de 'infraestructura' es harapienta porque hay grandes diferencias entre diferentes DBMS sobre lo que constituye una 'base de datos' versus una 'instancia de servidor', por ejemplo. Add : La pregunta está etiquetada 'mysql', así que tal vez esos pensamientos no son completamente relevantes.)

Añadir: Un problema más: con varios clientes en una sola base de datos, cada consulta SQL necesitará asegurarse de que se eligen 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 va a tener 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ósito.

Claramente, StackOverflow (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 empresas, no creo que fuera aceptable (para las empresas, y posiblemente no para las personas legales) compartir bases de datos.

 22
Author: Jonathan Leffler,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-11-01 16:37:02
  • DESARROLLO Para un desarrollo rápido, utilice una base de datos por cliente. Piense en lo fácil que será hacer copias de seguridad, restaurar o eliminar los datos de un cliente. O para medir / monitorear / facturar el uso. No necesitarás escribir código para hacerlo por ti mismo, solo usa las primitivas de tu base de datos.

  • RENDIMIENTO Para obtener rendimiento, utilice 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 tiene muchos clientes pequeños (piense en hotmail) probablemente debería trabajar en una sola base de datos. Y tener todas las tareas administrativas como registro, eliminación,migración de datos, etc. totalmente automatizado y expuesto en una interfaz amigable. Si planea tener docenas o hasta unos pocos cientos de clientes grandes, puede trabajar en una base de datos por cliente y tener scripts de administración del sistema en su lugar que pueden ser operados por su personal de atención al cliente.

 13
Author: flybywire,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-02-15 12:54:20

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

Hay otro gran artículo 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 de la base de datos, es posible que desee usar [row level security], dependiendo del DBMS que use (estoy seguro de que es posible en MS SQL Server y Oracle, probablemente también en IBM DB2). Puedes usar trucos como seguridad a nivel de fila en MySQL para lograr resultados similares (vistas + disparadores).

 12
Author: Maksymilian Majer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-02-06 18:42:56

Para la multitenencia, el rendimiento normalmente aumentará cuantos más recursos logre compartir entre los inquilinos, consulte

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

Así que si puede, vaya con la base de datos única. Estoy de acuerdo en que los problemas de seguridad solo se producirían 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 (de modo que cada usuario autenticado obtenga una vista).

También hay formas de proporcionar extensibilidad. Por ejemplo, puede crear una sola tabla con atributos de extensión (con claves tenant, registro base e id de atributo de extensión). También puede crear tablas de extensión por inquilino, de modo que cada inquilino tenga su propio esquema de extensión.

 10
Author: Martin v. Löwis,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-11-01 08:04:28

Cuando está diseñando una base de datos multi-tenant, generalmente tiene tres opciones:

  1. Tener una base de datos por inquilino
  2. Tener un esquema por tenant
  3. Que todos los inquilinos compartan la misma(s) tabla (s)

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

En la práctica, cada uno de los tres diseños las opciones, con suficiente esfuerzo, pueden abordar preguntas sobre 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á construyendo para escala: Haga que todos los inquilinos compartan la misma(s) tabla (s)
  • Si está construyendo para aislamiento: Cree una base de datos por inquilino

Por ejemplo, Google y Salesforce siguen el primer patrón y sus inquilinos comparten las mismas tablas. Stackoverflow, 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 está optimizando el diseño de su base de datos. Este artículo sobre el diseño de su base de datos SaaS para scale habla sobre las compensaciones y proporciona un resumen en el contexto de PostgreSQL.

 5
Author: ozgune,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:09:39

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

 4
Author: da5id,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-11-01 20:52:06

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

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

Además," sharding " una aplicación multi-tenant es probable€ para ser lo correcto a hacer con el tiempo, a medida que su aplicación se hace más y más grande.

Sharding no significa, sin embargo, una base de datos (o instancia) por tenant, sino una por shard o conjunto de shards, que puede tener varios tenants cada uno. Tendrá que descubrir los parámetros de ajuste adecuados por sí mismo, probablemente en la producción (por lo tanto, probablemente debe ser bastante sintonizable desde el principio)

€ No puedo garantizarlo.

 4
Author: MarkR,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-11-01 21:07:59

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

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

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

 0
Author: jjriv,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-01-02 23:15:17