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

147

После этого комментария к одному из моих вопросов, я думаю, что лучше использовать одну базу данных с 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 работал очень хорошо, даже если структура приложения полностью изменилась:

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

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

Strae
источник
«Все мои базы данных / схемы будут иметь одинаковую структуру!» Вы имеете в виду, что все они имеют одинаковую структуру? Или никогда?
Усама Аль-Маадид
Извините, да, они все имеют одну и ту же структуру навсегда: если я изменю одну, я изменю их все;)
Strae
Если у вас 1000 клиентов, значит, вам нужно обновить 1000 схем?
Джошуа Партоги
@jpartogi: да, но мне нужно обновить только структуру таблиц, а не данные.
Strae
Итак, чем ты занялся в конце концов? Один вопрос, хотя, хотя производительность запросов и т. Д. Может контролироваться табличными пространствами, схемами, приводящими к эквивалентной производительности multi-db против multi-schema, любое влияние на журналы WAL ???
Капил

Ответы:

113

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

kquinn
источник
33
Это. Postgres не позволяет вам делать запросы к базам данных, что может быть довольно раздражающим.
Мэтт б
81
«Наличие большого количества баз данных при установке PostgreSQL может стать проблематичным» - уточните, пожалуйста; это вообще проблематично или в данном конкретном случае и почему?
akaihola
33
«Самым распространенным вариантом использования нескольких схем в базе данных является создание приложения« программное обеспечение как услуга », в котором у каждого клиента есть своя собственная схема. Хотя этот метод кажется убедительным, мы настоятельно рекомендуем отказаться от него, поскольку он вызвал многочисленные случаи эксплуатационные проблемы. Например, даже умеренное количество схем (> 50) может серьезно повлиять на производительность инструмента моментальных снимков базы данных Heroku " devcenter.heroku.com/articles/heroku-postgresql
Нил Макгиган
16
@NeilMcGuigan: Интересно, что это, кажется, противоположный вывод из (принятого) ответа Квинна.
карбюрация
8
Однако наличие одной базы данных с множеством схем практически исключает возможность создания единой схемы из них. Я использую одну базу данных postgres с более чем 3000 схемами, и pg_dump просто завершается с ошибкой нехватки памяти, если вы пытаетесь сбросить одну схему. Интересно, если бы это было иначе, у меня было бы 3000 баз данных.
Мачисуджи
27

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

  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()
Strae
источник
14

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

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

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

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

Питер Мортенсен
источник
4
... и поэтому у меня будет 1 база данных с внутренними схемами: $ customer1_user_schema, $ customer2_user_schema, $ customer3_user_schema, $ customer1_documents_schema, $ customer2_documents_schema, $ customer3_documents_schema? Мм ... не кажется надежным способом ... а как насчет производительности? А как насчет кода моего приложения (будет php и python)? так много схем ..
Strae
7
@Strae: я читаю это как: у каждого клиента есть своя база данных customer1_database, customer2_database и внутри этих баз данных у вас есть user_schema, documents_schema.
frankhommers
6

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

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

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

етах
источник
4

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

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

Троэльс Арвин
источник