Recomendaría buscar información en las listas de correo de PostgreSQL sobre el diseño multiusuario. Ha habido mucha discusión allí, y la respuesta se reduce a "depende". Hay ventajas y desventajas en todos los sentidos entre el aislamiento garantizado, el rendimiento y la capacidad de mantenimiento.
Un enfoque común es usar una sola base de datos, pero un esquema (espacio de nombres) por cliente con la misma estructura de tabla en cada esquema, además de un esquema común o compartido para los datos que son iguales en todos ellos. Un esquema de PostgreSQL es como una "base de datos" de MySQL en la que puede consultar diferentes esquemas, pero están aislados de forma predeterminada. Con los datos del cliente en un esquema separado, puede usar search_path
configuración, generalmente a través de ALTER USER
customername SET search_path = 'customerschema, sharedschema'
para garantizar que cada cliente vea sus datos y solo sus datos.
Para obtener protección adicional, debe REVOKE
ALL FROM SCHEMA customerschema FROM public
luego GRANT
ALL ON SCHEMA customerschema TO thecustomer
por lo que son los únicos con acceso a él, haciendo lo mismo con cada una de sus mesas. Su grupo de conexiones puede iniciar sesión con una cuenta de usuario fija que tiene no GRANT
ed acceso a cualquier esquema de cliente, pero tiene derecho a SET ROLE
convertirse en cualquier cliente. (Hágalo otorgándoles la membresía de cada rol de cliente con NOINHERIT configurado para que los derechos deban reclamarse explícitamente a través de SET ROLE
). La conexión debería inmediatamente SET ROLE
al cliente con 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 incorrecto. Siempre que el grupo haga un DISCARD ALL
y/o un RESET ROLE
antes de entregar las conexiones al próximo cliente, eso le brindará un aislamiento muy fuerte sin la frustración de las conexiones individuales por usuario.
Si el entorno de su aplicación web no tiene un conjunto de conexiones decente incorporado (digamos, está usando PHP con conexiones persistentes), entonces realmente necesita poner un buen conjunto de conexiones
en su lugar entre Pg y el servidor web de todos modos, porque demasiadas conexiones al backend dañarán su rendimiento. PgBouncer
y PgPool-II
son las mejores opciones, y fácilmente pueden encargarse de hacer DISCARD ALL
y RESET ROLE
para usted durante el traspaso de la conexión.
La principal desventaja de este enfoque es la sobrecarga de mantener tantas tablas, ya que su conjunto base de tablas no compartidas se clona para cada cliente. Se acumulará a medida que crezca el número de clientes, hasta el punto en que la gran cantidad de tablas para examinar durante las ejecuciones de vacío automático comienza a ser costosa y donde cualquier operación que se escale en función de la cantidad total de tablas en la base de datos se ralentiza. Este es un problema mayor si está pensando en tener muchos miles o decenas de miles de clientes en la misma base de datos, pero fuertemente Te recomendamos que hagas algunas pruebas de escalado con este diseño utilizando datos ficticios antes de comprometerte con él.
Es probable que el enfoque ideal sean tablas individuales con seguridad automática a nivel de fila que controle 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 al agregar la infraestructura y las API adecuadas, pero no está en 9.1.