En el extremo inferior, básicamente se reduce a "¿puede decir absolutamente que no tiene datos compartidos?" A diferencia de mysql, la base de datos es un límite absoluto en postgresql. No puedes SELECT zip_code FROM common.city_zip WHERE city=...
si vas con bases de datos separadas (al menos no sin dblink
).
Si tiene datos compartidos, el "esquema" de postgresql es similar a lo que mysql llama una "base de datos" . Puede CREATE SCHEMA clienta; CREATE TABLE clienta.customer (...);
. Crearía un esquema para cada cliente, el usuario de ese cliente tendría su esquema primero en su ruta de búsqueda, y se otorgarían permisos para que el usuario del Cliente A tuviera acceso a clienta
los public
esquemas (y sus tablas).
Su problema será que en el extremo superior del número de clientes, cada tabla se almacena como un archivo, por lo tanto, ya sea que vaya con una base de datos por cliente, un esquema por cliente o use algo como ${client}_customer
para los nombres de sus tablas, lo hará probablemente se encuentre con los límites del descriptor de archivo con 10k clientes incluso si solo tuviera una tabla por cliente (más un descriptor de archivo por conexión). Por supuesto, puede ajustar el número máximo de descriptores de archivo del núcleo sobre la marcha utilizando sysctl, pero el límite por proceso (ulimit) requerirá reiniciar postgresql si lo configura demasiado bajo la primera vez.
La alternativa es tener "una gran tabla" con una columna de cliente que identifique a qué cliente pertenece esa fila (idealmente, por nombre de usuario si tiene un usuario por cliente, esto hace que las cosas debajo de MUCHO sean más fáciles). Al no otorgar ningún acceso a esta tabla por parte de los clientes, puede crear vistas específicas del cliente (o usar session_user
para identificar al cliente actual). Sin embargo, las actualizaciones no se pueden hacer directamente a través de una vista. Necesitaría tener funciones definidas para insertar / actualizar / eliminar en la tabla (un conjunto de funciones por cliente o usar session_user
) con las funciones SECURITY DEFINER
que se ejecutan como un usuario especial con permiso para insertar / actualizar / eliminar en las tablas (nota : session_user
se usa porque user
ycurrent_user
se basan en el contexto actual, y dentro de una función DEFINIDOR DE SEGURIDAD, este siempre sería el usuario que definió la función).
En cuanto al rendimiento, más allá del problema de fd, honestamente no sé qué pasaría con 10000 bases de datos en postgresql, en comparación con tener una tabla grande con el valor de datos de 10000 clientes. El diseño de índice adecuado debería evitar que la tabla grande sea lenta para consultar.
Diré que fui con bases de datos separadas para cada cliente aquí (agregamos servidores para mantener el sistema utilizable, cambiando las bases de datos de clientes a nuevos servidores según sea necesario, por lo que nunca llegaremos a 10k bases de datos en un servidor). He tenido que restaurar los datos de clientes individuales a partir de copias de seguridad para la depuración o debido a un error del usuario de forma regular, algo que sería una pesadilla absoluta en el diseño de "una gran mesa". Además, si tiene la intención de vender la personalización de su producto a sus clientes, el diseño de "una gran mesa" podría terminar obstaculizando su capacidad de personalizar el modelo de datos.
pg_dump -n
(¡asegúrese de volcar su esquema común también!) Para enumerar el esquema:psql -E
entonces\dn
Sin más detalles sobre su aplicación, es difícil decir que obtendrá esta seguridad adicional de esta configuración. Si cada cliente se conecta a la aplicación web y hay un usuario compartido de la aplicación web a la base de datos, entonces no ha aislado sus datos de una manera diferente al uso de una sola base de datos monolítica. Acceder a sus datos a través de procedimientos almacenados correctamente parametrizados le proporcionará el nivel de aislamiento que está buscando sin el dolor administrativo de administrar más de 10,000 bases de datos en cualquier número de servidores.
Personalmente, ejecuté una configuración similar en un único servidor de base de datos utilizando nada más que procedimientos almacenados parametrizados que afectan a una sola base de datos. Si puede garantizar que el único acceso a la base de datos es a través de procedimientos almacenados, no hay peligro de que los datos se mezclen en los resultados.
Si desea seguir adelante con su diseño, estas son mis principales preocupaciones:
ulimit -n
) en su sistema operativo hostfuente
SELECT * WHERE clientId = 3
, tiene una fuga de seguridad.