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

Я майже забув: усі мої бази даних / схеми завжди матимуть однакову структуру!

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


"всі мої бази / схеми будуть колись мати однакову структуру!" ти маєш на увазі, що всі вони мають однакову структуру? Або ніколи?
Осама Аль-Мадейд

Вибачте, так, всі вони мають одну і ту ж структуру назавжди: якщо я зміню її, я зміню всіх;)
Strae

Якщо у вас 1000 клієнтів, це означає, що вам доведеться оновити схему 1000?
Джошуа Партогі

@jpartogi: так, але я повинен оновлювати лише структуру таблиць, а не дані.
Strae

Отже, для чого ти нарешті пішов? Хоча одне питання, хоча виконання запитів тощо може контролюватися табличними просторами, схемами, що призводять до еквівалентної продуктивності мульти-db vs multi-схем, будь-якого впливу на WAL-журнали ???
Капіль

Відповіді:


113

"Схема" PostgreSQL приблизно така ж, як "база даних" MySQL. Наявність багатьох баз даних для установки PostgreSQL може стати проблематичним; мати багато схем буде працювати без проблем. Отже, ви обов'язково хочете мати одну базу даних та кілька схем у цій базі даних.


33
Це. Postgres не дозволяє проводити запити по базам даних, що може бути дуже дратує.
мат b

81
"Наявність багатьох баз даних при установці PostgreSQL може стати проблематичною" - уточнюйте; це проблематично в цілому або в цьому конкретному випадку, і чому?
akaihola

33
"Найпоширенішим випадком використання для використання декількох схем у базі даних є побудова програмного забезпечення як-до-служби, де кожен клієнт має власну схему. Хоча ця методика здається переконливою, ми наполегливо рекомендуємо проти неї, оскільки вона спричинила численні випадки Наприклад, навіть помірне число схем (> 50) може сильно вплинути на ефективність інструменту знімків знімків бази даних Heroku " devcenter.heroku.com/articles/heroku-postgresql
Ніл МакГуган

16
@NeilMcGuigan: Цікаво, що, здається, є протилежний висновок з відповіді kquinn (прийнятої).
карбокація

8
Наявність однієї бази даних з багатьма схемами дозволить практично неможливо скинути одну схему з них. Я запускаю єдину базу даних Postgres з більш ніж 3000 схемами, і pg_dump просто не вдається з помилкою пам'яті, якщо ви спробуєте скинути одну схему. Цікаво, чи це було б інакше, якби я мав натомість 3000 баз даних.
Макісуджі

27

Однозначно, я піду підходити до схем одного db-many-схем. Це дозволяє мені скинути всю базу даних, але відновити лише одну дуже легко, багатьма способами:

  1. Вивантажте db (усі схеми), завантажте дамп у новий db, скиньте лише потрібну мені схему та відновіть назад у головному db.
  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()

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.
франкхоммери

6

У контексті PostgreSQL я рекомендую використовувати один db з декількома схемами, як ви можете (наприклад) UNION ALL для схем, але не для баз даних. З цієї причини база даних дійсно повністю ізольована від іншої бази даних, тоді як схеми не ізольовані від інших схем у цій же базі даних.

Якщо вам з певних причин доведеться консолідувати дані за схемами в майбутньому, це буде легко зробити через декілька схем. За допомогою декількох баз даних вам знадобиться кілька db-з'єднань і збирати та об'єднувати дані з кожної бази даних "вручну" за логікою програми.

Останні мають переваги в деяких випадках, але, здебільшого, я думаю, що підхід "одна база даних-кілька схем" є більш корисним.


4

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

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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.