PostgreSQL: ¿Es mejor usar múltiples bases de datos con un esquema cada una, o una base de datos con múltiples esquemas?

147

Después de este comentario a una de mis preguntas, estoy pensando si es mejor usar una base de datos con esquemas X o viceversa.

Mi situación: estoy desarrollando una aplicación web donde, cuando las personas se registran, creo (en realidad) una base de datos (no, no es una red social: todos deben tener acceso a sus propios datos y nunca ver los datos del otro usuario) .

Esa es la forma en que utilicé la versión anterior de mi aplicación (que todavía se ejecuta en MySQL): a través de la API de Plesk, para cada registro, hago:

  1. Crear un usuario de base de datos con privilegios limitados;
  2. Cree una base de datos a la que pueda acceder solo el usuario creado anteriormente y el superusuario (para mantenimiento)
  3. Poblar la base de datos

Ahora, tendré que hacer lo mismo con PostgreSQL (el proyecto está madurando y MySQL ... no cumple con todas las necesidades).

Necesito tener todas las copias de seguridad de bases de datos / esquemas independientes: pg_dump funciona perfectamente en ambos sentidos, y lo mismo para los usuarios que se pueden configurar para acceder a un solo esquema o una base de datos.

Entonces, suponiendo que son usuarios de PostgreSQL más experimentados que yo, ¿cuál creen que es la mejor solución para mi situación y por qué?

¿Habrá diferencias de rendimiento con la base de datos $ x en lugar de los esquemas $ x? ¿Y qué solución será mejor mantener en el futuro (confiabilidad)?

Todas mis bases de datos / esquemas siempre tendrán la misma estructura!

Para el problema de las copias de seguridad (usando pg_dump), tal vez sea mejor usar una base de datos y muchos esquemas, volcar todos los esquemas a la vez: recuperar será bastante simple cargar el volcado principal en una máquina de desarrollo y luego volcar y restaurar solo el esquema necesario: allí es un paso adicional, pero eliminar todo el esquema parece más rápido que hacerlo uno por uno.

ACTUALIZACIÓN 2012

Bueno, la estructura y el diseño de la aplicación cambiaron mucho durante los últimos dos años. Todavía estoy usando el one db with many schemasenfoque, pero aún así, tengo una base de datos para cada versión de mi aplicación:

Db myapp_01
    \_ my_customer_foo_schema
    \_ my_customer_bar_schema
Db myapp_02
    \_ my_customer_foo_schema
    \_ my_customer_bar_schema

Para las copias de seguridad, estoy volcando cada base de datos regularmente y luego moviendo las copias de seguridad en el servidor de desarrollo.

También estoy usando la copia de seguridad PITR / WAL pero, como dije antes, no es probable que tenga que restaurar toda la base de datos de de una vez ... por lo que probablemente se descarte este año (en mi situación no es el mejor enfoque )

El enfoque one-db-many-schema funcionó muy bien para mí desde ahora, incluso si la estructura de la aplicación cambia totalmente:

Casi se me olvida: ¡todas mis bases de datos / esquemas siempre tendrán la misma estructura!

... ahora, cada esquema tiene su propia estructura que cambia dinámicamente reaccionando al flujo de datos de los usuarios.

Strae
fuente
"¡Todas mis bases de datos / esquemas tendrán la misma estructura!" ¿Quieres decir que todos tienen la misma estructura? ¿O nunca?
Osama Al-Maadeed
Lo siento, sí, todos tienen la misma estructura para siempre: si cambio uno, los cambiaré a todos;)
Strae el
Si tiene 1000 clientes, ¿eso significa que tiene que actualizar 1000 esquemas?
Joshua Partogi
@jpartogi: sí, pero tengo que actualizar solo la estructura de tablas, no los datos.
Strae
Entonces, ¿por qué fuiste finalmente? Sin embargo, una pregunta, aunque el rendimiento de las consultas, etc. puede controlarse mediante espacios de tabla, esquemas que resultan en un rendimiento equivalente de multi-db vs multi-esquema, ¿cualquier impacto en los registros de WAL?
Kapil

Respuestas:

113

Un "esquema" de PostgreSQL es más o menos lo mismo que una "base de datos" de MySQL. Tener muchas bases de datos en una instalación de PostgreSQL puede ser problemático; Tener muchos esquemas funcionará sin problemas. Así que definitivamente quieres ir con una base de datos y múltiples esquemas dentro de esa base de datos.

kquinn
fuente
33
Esta. Postgres no le permite realizar consultas en bases de datos, lo que puede ser bastante molesto.
mate b
81
"Tener muchas bases de datos en una instalación de PostgreSQL puede ser problemático" - aclare; ¿Es problemático en general o en este caso específico, y por qué?
akaihola
33
"El caso de uso más común para usar múltiples esquemas en una base de datos es crear una aplicación de software como servicio en la que cada cliente tenga su propio esquema. Si bien esta técnica parece convincente, recomendamos enfáticamente que haya causado numerosos casos de problemas operativos. Por ejemplo, incluso un número moderado de esquemas (> 50) puede afectar gravemente el rendimiento de la herramienta de instantáneas de la base de datos de Heroku " devcenter.heroku.com/articles/heroku-postgresql
Neil McGuigan
16
@NeilMcGuigan: Curiosamente, esa parece ser la conclusión opuesta de la respuesta (aceptada) de kquinn.
carbocation
8
Sin embargo, tener una base de datos con muchos esquemas hará que sea prácticamente imposible volcar un solo esquema de esos. Estoy ejecutando una sola base de datos postgres con más de 3000 esquemas y pg_dump simplemente falla con un error de falta de memoria si intenta volcar un solo esquema. Me pregunto si esto sería diferente si tuviera bases de datos I 3000 en su lugar.
Machisuji
27

Definitivamente, iré por el enfoque de uno-db-muchos-esquemas. Esto me permite volcar toda la base de datos, pero restaurar solo una muy fácilmente, de muchas maneras:

  1. Volcar el db (todo el esquema), cargar el volcado en un nuevo db, volcar solo el esquema que necesito y restaurar de nuevo en el db principal.
  2. Volcar el esquema por separado, uno por uno (pero creo que la máquina sufrirá más de esta manera, ¡y espero 500 esquemas!)

De lo contrario, buscando en Google he visto que no hay un procedimiento automático para duplicar un esquema (usando uno como plantilla), pero muchos sugieren de esta manera:

  1. Crear un esquema de plantilla
  2. Cuando necesite duplicar, cámbiele el nombre por un nuevo nombre
  3. Arrojarlo
  4. Renombrarlo de nuevo
  5. Restaurar el volcado
  6. La magia está hecha.

He escrito dos filas en Python para hacer eso; Espero que puedan ayudar a alguien (código escrito en 2 segundos, no lo use en producción):

import os
import sys
import pg

# Take the new schema name from the second cmd arguments (the first is the filename)
newSchema = sys.argv[1]

# Temperary folder for the dumps
dumpFile = '/test/dumps/' + str(newSchema) + '.sql'

# Settings
db_name = 'db_name'
db_user = 'db_user'
db_pass = 'db_pass'
schema_as_template = 'schema_name'

# Connection
pgConnect = pg.connect(dbname= db_name, host='localhost', user= db_user, passwd= db_pass)

# Rename schema with the new name
pgConnect.query("ALTER SCHEMA " + schema_as_template + " RENAME TO " + str(newSchema))

# Dump it
command = 'export PGPASSWORD="' + db_pass + '" && pg_dump -U ' + db_user + ' -n ' + str(newSchema) + ' ' + db_name + ' > ' + dumpFile
os.system(command)

# Rename back with its default name
pgConnect.query("ALTER SCHEMA " + str(newSchema) + " RENAME TO " + schema_as_template)

# Restore the previous dump to create the new schema
restore = 'export PGPASSWORD="' + db_pass + '" && psql -U ' + db_user + ' -d ' + db_name + ' < ' + dumpFile
os.system(restore)

# Want to delete the dump file?
os.remove(dumpFile)

# Close connection
pgConnect.close()
Strae
fuente
14

Yo diría, ve con múltiples bases de datos Y múltiples esquemas :)

Los esquemas en PostgreSQL se parecen mucho a los paquetes en Oracle, en caso de que esté familiarizado con ellos. Las bases de datos están destinadas a diferenciar entre conjuntos completos de datos, mientras que los esquemas son más como entidades de datos.

Por ejemplo, podría tener una base de datos para una aplicación completa con los esquemas "UserManagement", "LongTermStorage", etc. "UserManagement" contendría la tabla "User", así como todos los procedimientos almacenados, disparadores, secuencias, etc. que son necesarios para la gestión de usuarios.

Las bases de datos son programas completos, los esquemas son componentes.

Peter Mortensen
fuente
44
... y así tendré 1 base de datos, dentro de los esquemas: $ customer1_user_schema, $ customer2_user_schema, $ customer3_user_schema, $ customer1_documents_schema, $ customer2_documents_schema, $ customer3_documents_schema? Mh ... no parece una forma confiable ... y ¿qué pasa con el rendimiento? ¿Y qué hay del código de mi aplicación (será php y python)? tantos esquemas ..
Strae
77
@Strae: Estoy leyendo esto como: cada cliente tiene su base de datos customer1_database, customer2_database y dentro de esas bases de datos tiene user_schema, documents_schema.
frankhommers
6

En un contexto PostgreSQL, recomiendo usar un db con múltiples esquemas, ya que puede (por ejemplo) UNION ALL en todos los esquemas, pero no en las bases de datos. Por esa razón, una base de datos está realmente completamente aislada de otra base de datos, mientras que los esquemas no están aislados de otros esquemas dentro de la misma base de datos.

Si, por alguna razón, tiene que consolidar datos en esquemas en el futuro, será fácil hacerlo en múltiples esquemas. Con múltiples bases de datos, necesitaría múltiples conexiones db y recopilar y fusionar los datos de cada base de datos "manualmente" por lógica de aplicación.

Estos últimos tienen ventajas en algunos casos, pero en su mayor parte creo que el enfoque de una base de datos múltiple es más útil.

emax
fuente
4

Varios esquemas deberían ser más livianos que varias bases de datos, aunque no puedo encontrar una referencia que lo confirme.

Pero si realmente desea mantener las cosas muy separadas (en lugar de refactorizar la aplicación web para que se agregue una columna de "cliente" a sus tablas), es posible que desee utilizar bases de datos separadas: afirmo que puede hacer restauraciones más fácilmente la base de datos de un cliente particular de esta manera, sin molestar a los otros clientes.

Troels Arvin
fuente