PostgreSQL: лучше ли использовать несколько баз данных с одной схемой каждая или одну базу данных с несколькими схемами?

После этого комментария к одному из моих вопросов, я думаю, что лучше использовать одну базу данных с X-схемами или наоборот.

Моя ситуация: я разрабатываю веб-приложение, в котором, когда люди регистрируются, я создаю (на самом деле) базу данных (нет, это не социальная сеть: каждый должен иметь доступ к своим данным и никогда не видеть данные другого пользователя),

То, что я использовал для предыдущей версии моего приложения (которая все еще работает на MySQL): через API Plesk для каждой регистрации я делаю:

  1. Создать базу данных пользователя с ограниченными правами;
  2. Создайте базу данных, к которой может обращаться только предыдущий созданный пользователь и суперпользователь (для обслуживания)
  3. Заполните базу данных

Теперь мне нужно сделать то же самое с PostgreSQL (проект становится зрелым, а MySQL... не удовлетворяет всем требованиям).

Мне нужно, чтобы все резервные копии баз данных/схем были независимыми: pg_dump отлично работает в обоих направлениях и одинаково для пользователей, которые могут быть настроены для доступа только к одной схеме или одной базе данных.

Итак, если вы являетесь более опытным пользователем PostgreSQL, чем я, что вы считаете лучшим решением для моей ситуации и почему?

Будут ли различия в производительности при использовании базы данных $ x вместо схем $ x? И какое решение будет лучше поддерживать в будущем (надежность)?

Все мои базы данных/схемы всегда будут иметь одинаковую структуру!

Что касается проблемы с резервными копиями (с использованием pg_dump), возможно, лучше использовать одну базу данных и несколько схем, создавая дамп всех схем одновременно: восстановление будет довольно простой загрузкой основного дампа на машине разработчика, а затем выгрузкой и восстановлением только необходимой схемы: это еще один шаг, но выгрузка всей схемы кажется быстрее, чем выгрузка одной за другой.

ОБНОВЛЕНИЕ 2012

Ну, структура приложений и дизайн сильно изменились за последние два года. Я по-прежнему использую подход с одной базой данных one db with many schemas, но, тем не менее, у меня есть одна база данных для каждой версии моего приложения:

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

Для резервного копирования я регулярно выгружаю каждую базу данных, а затем перемещаю резервные копии на сервер разработки.

Я также использую резервное копирование PITR/WAL, но, как я уже говорил, маловероятно, что мне придется восстанавливать всю базу данных одновременно... поэтому она, вероятно, будет закрыта в этом году (в моей ситуации это не лучший подход).

С тех пор подход one-db-many-schema очень хорошо работал для меня, даже если структура приложения полностью изменилась:

Я почти забыл: все мои базы данных/схемы всегда будут иметь одинаковую структуру!

... теперь каждая схема имеет свою собственную структуру, которая динамически изменяется, реагируя на поток данных пользователя.

Ответ 1

PostgreSQL "схема" примерно такая же, как база данных MySQL. Наличие многих баз данных на установке PostgreSQL может стать проблематичным; имея много схем, будет работать без проблем. Поэтому вы определенно хотите пойти с одной базой данных и несколькими схемами в этой базе данных.

Ответ 2

Определенно, я пойду на подход "одна дБ-много-схем". Это позволяет мне сбросить всю базу данных, но восстановить ее очень легко, разными способами:

  1. Сбросьте базу данных (всю схему), загрузите дамп в новую базу данных, скопируйте только нужную мне схему и восстановите обратно в основную базу данных.
  2. Дамп схемы по отдельности, один за другим (но я думаю, что таким образом машина пострадает больше - и я ожидаю, как 500 схем!)

В противном случае, поглядывая вокруг, я видел, что не существует автоматической процедуры для дублирования схемы (с использованием одной в качестве шаблона), но многие предлагают такой способ:

  1. Создать шаблон-схему
  2. Когда нужно дублировать, переименуйте его с новым именем
  3. Дамп это
  4. Переименовать его обратно
  5. Восстановить дамп
  6. Волшебство сделано.

Я написал две строки в Python, чтобы сделать это; Я надеюсь, что они могут кому-то помочь (за 2 секунды написанного кода, не используйте его в производстве):

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()

Ответ 3

Я бы сказал, пойти с несколькими базами данных и несколькими схемами :)

Схемы в PostgreSQL очень похожи на пакеты в Oracle, если вы знакомы с ними. Базы данных предназначены для различения целых наборов данных, в то время как схемы больше похожи на объекты данных.

Например, у вас может быть одна база данных для всего приложения со схемами "UserManagement", "LongTermStorage" и так далее. Тогда "UserManagement" будет содержать таблицу "User", а также все хранимые процедуры, триггеры, последовательности и т.д., Необходимые для управления пользователями.

Базы данных - это целые программы, схемы - это компоненты.

Ответ 4

Ряд схем должен быть более легковесным, чем ряд баз данных, хотя я не могу найти ссылку, подтверждающую это.

Но если вы действительно хотите сохранить отдельные вещи (вместо рефакторинга веб-приложения, чтобы столбец "клиент" был добавлен к вашим таблицам), вы все равно можете использовать отдельные базы данных: я утверждаю, что вам легче будет восстанавливать таким образом, база данных конкретных клиентов - не мешая другим клиентам.

Ответ 5

В контексте PostgreSQL я рекомендую использовать одну базу данных с несколькими схемами, как вы можете (например) UNION ALL для всех схем, но не для баз данных. По этой причине база данных действительно полностью изолирована от другой базы данных, в то время как схемы не изолированы от других схем в той же базе данных.

Если вам -for потребуется некоторое reason- для консолидации данных по схемам в будущем, это будет легко сделать по нескольким схемам. При наличии нескольких баз данных вам потребуется несколько db-соединений, а также сбор и объединение данных из каждой базы данных "вручную" с помощью логики приложения.

Последние имеют преимущества в некоторых случаях, но для большей части я думаю, что подход "одна база данных - несколько схем" более полезен.

Ответ 6

Получите ясность вещей:

Во-первых, большую часть времени вы хотели бы сделать некоторые базы данных доступными только для чтения, а некоторые - для чтения/записи. Поэтому сохранить схему, используемую только для чтения, можно в разных базах данных, а схему чтения/записи - в другой базе данных, хотя я бы посоветовал вам сохранить максимум 25-30 схем в одной базе данных, поскольку вы не хотите создавать загрузка базы данных для журналов для всей схемы.

Вот одна статья, если вы хотите прочитать больше.