PostgreSQL: лучше ли использовать несколько баз данных с одной схемой каждая или одну базу данных с несколькими схемами?
После этого комментария к одному из моих вопросов, я думаю, что лучше использовать одну базу данных с X-схемами или наоборот.
Моя ситуация: я разрабатываю веб-приложение, в котором, когда люди регистрируются, я создаю (на самом деле) базу данных (нет, это не социальная сеть: каждый должен иметь доступ к своим данным и никогда не видеть данные другого пользователя),
То, что я использовал для предыдущей версии моего приложения (которая все еще работает на MySQL): через API Plesk для каждой регистрации я делаю:
- Создать базу данных пользователя с ограниченными правами;
- Создайте базу данных, к которой может обращаться только предыдущий созданный пользователь и суперпользователь (для обслуживания)
- Заполните базу данных
Теперь мне нужно сделать то же самое с 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
Определенно, я пойду на подход "одна дБ-много-схем". Это позволяет мне сбросить всю базу данных, но восстановить ее очень легко, разными способами:
- Сбросьте базу данных (всю схему), загрузите дамп в новую базу данных, скопируйте только нужную мне схему и восстановите обратно в основную базу данных.
- Дамп схемы по отдельности, один за другим (но я думаю, что таким образом машина пострадает больше - и я ожидаю, как 500 схем!)
В противном случае, поглядывая вокруг, я видел, что не существует автоматической процедуры для дублирования схемы (с использованием одной в качестве шаблона), но многие предлагают такой способ:
- Создать шаблон-схему
- Когда нужно дублировать, переименуйте его с новым именем
- Дамп это
- Переименовать его обратно
- Восстановить дамп
- Волшебство сделано.
Я написал две строки в 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 схем в одной базе данных, поскольку вы не хотите создавать загрузка базы данных для журналов для всей схемы.
Вот одна статья, если вы хотите прочитать больше.