2011-12-08 12 views
5

tienen una aplicación en la que muchas empresas publican información. los datos de cada empresa son independientes: no hay superposición de datos.en postgresql, ¿son las particiones o las bases de datos múltiples más eficientes?

en cuanto al rendimiento, es mejor:

  • mantener la identificación de la compañía en cada fila de cada tabla y cada índice se utiliza?
  • partición de cada mesa de acuerdo con la identificación de la compañía
  • partición y crear un usuario para acceder a cada empresa para garantizar la seguridad
  • crear varias bases de datos, uno para cada empresa

aplicación basada en web con conexiones persistentes .

mis pensamientos:

  • nuevas conexiones pg son caros, por lo que una sola base de datos crea menos nuevas conexiones
  • tener sólo una copia del diccionario parece más eficiente que 200 más o menos
  • múltiples bases de datos son Ciertamente más seguro del error del programador
  • si las especificaciones de la aplicación deberían cambiar para que las empresas compartan, la base de datos múltiples sería difícil de implementar

Respuesta

14

Recomiendo buscar información en las listas de correo de PostgreSQL sobre el diseño de varios usuarios. Ha habido mucha discusión allí, y la respuesta se reduce a "depende". Hay compensaciones en todos los sentidos entre el aislamiento garantizado, el rendimiento y la capacidad de mantenimiento.

Un enfoque común es utilizar una sola base de datos, pero schema (espacio de nombres) por cliente con la misma estructura de tabla en cada esquema, más un esquema compartido o común para datos iguales en todos ellos. Un esquema de PostgreSQL es como una "base de datos" de MySQL porque puede consultar en diferentes esquemas, pero están aislados por defecto. Con los datos del cliente en un esquema separado, puede usar la configuración search_path, generalmente a través del ALTER USERcustomername SET search_path = 'customerschema, sharedschema' para asegurarse de que cada cliente vea sus datos y solo sus datos.

Para protección adicional, usted debe REVOKEALL FROM SCHEMA customerschema FROM public continuación GRANTALL ON SCHEMA customerschema TO thecustomer por lo que son el único con cualquier acceso a él, haciendo lo mismo a cada una de sus mesas. Su grupo de conexiones puede iniciar sesión con una cuenta de usuario fija que tiene noGRANT acceso ed a cualquier esquema de cliente, pero tiene derecho a SET ROLE para convertirse en cliente. (Hágalo dandoles membresía de cada rol de cliente con NOINHERIT establecido para que los derechos se reclamen explícitamente a través del SET ROLE). La conexión debe ser inmediatamente SET ROLE para el cliente en el que está operando actualmente. Eso le permitirá evitar la sobrecarga de hacer nuevas conexiones para cada cliente mientras mantiene una fuerte protección contra el error del programador que conduce al acceso a los datos del cliente equivocado. Siempre que el grupo haga un DISCARD ALL y/o un RESET ROLE antes de entregar las conexiones al siguiente cliente, eso le dará un aislamiento muy fuerte sin la frustración de las conexiones individuales por usuario.

Si el entorno de aplicación web no tiene un pool de conexiones decente incorporado (por ejemplo, estás usando PHP con conexiones persistentes), entonces usted realmente necesita para poner un good connection pool en su lugar entre el paseo y el servidor web de todos modos, porque demasiadas conexiones con el servidor dañarán tu rendimiento. PgBouncer y PgPool-II son las mejores opciones, y pueden ocuparse de hacer el DISCARD ALL y RESET ROLE durante la entrega de la conexión.

El principal inconveniente de este enfoque es la sobrecarga con el mantenimiento de muchas tablas, ya que su conjunto básico de tablas no compartidas se clona para cada cliente. Sumará a medida que aumenten los números de clientes, hasta el punto en que la cantidad de tablas que se examinarán durante las ejecuciones de autovacuum comenzará a encarecerse y cualquier operación que se escale según el número total de tablas en el DB se ralentizará. Esto es más un problema si está pensando en tener miles o decenas de miles de clientes en la misma base de datos, pero I fuertemente le recomendamos que haga algunas pruebas de escala con este diseño utilizando datos ficticios antes de comprometerse.

Es probable que el enfoque ideal sean las tablas únicas con seguridad de nivel de fila automática que controla la visibilidad de la tupla, pero desafortunadamente eso es algo que PostgreSQL aún no tiene. Parece que está en camino gracias al trabajo de SEPostgreSQL que agrega infraestructura y API adecuadas, pero no está en 9.1.

+0

muchas gracias !! (Lo siento, he estado trabajando con MySQL últimamente y me ha hecho perder la cabeza.) El esquema debe ser una opción sobre múltiples bases de datos; de hecho, lo ha estado usando para otros proyectos. gran idea de establecer el rol después de conectar. han estado usando set path, pero la combinación de dos es mejor. –

+0

Sí, establecer la función le permite usar la seguridad de nivel de base de datos sin tanto dolor. Es genial. –

+0

... y recuerde utilizar un grupo de conexión decente como PgPool-II o PgBouncer si está utilizando algo primitivo en el lado del servidor web como PHP con conexiones persistentes. No es necesario si está utilizando algo así como un servidor de aplicaciones Java que hace su propia agrupación de conexiones en el servidor. –

Cuestiones relacionadas