web-dev-qa-db-ja.com

PostgreSQL:それぞれ1つのスキーマを持つ複数のデータベース、または複数のスキーマを持つ1つのデータベースを使用する方が良いでしょうか?

このコメント の私の質問の1つに、Xスキーマを持つ1つのデータベースを使用する方が良いか、またはその逆かを考えています。

私の状況:私は、人々が登録するときに(実際に)データベースを作成するWebアプリケーションを開発しています(いいえ、それはソーシャルネットワークではありません。誰もが自分のデータにアクセスでき、他のユーザーのデータを見ることはありません) 。

これは、以前のバージョンのアプリケーション(MySQLでまだ実行されている)で使用した方法です。PleskAPIを使用して、登録ごとに次のことを行います。

  1. 制限された特権を持つデータベースユーザーを作成します。
  2. 前に作成したユーザーとスーパーユーザーのみがアクセスできるデータベースを作成します(メンテナンス用)
  3. データベースに入力する

ここで、PostgreSQLでも同じことをする必要があります(プロジェクトは成熟しており、MySQL ...すべてのニーズを満たしていません)。

すべてのデータベース/スキーマバックアップを独立させる必要があります。pg_dumpは両方の方法で完全に機能し、1つのスキーマまたは1つのデータベースのみにアクセスするように構成できるユーザーでも同じです。

それで、あなたが私よりも経験豊富なPostgreSQLユーザーであると仮定して、私の状況に最適なソリューションは何だと思いますか?

$ xスキーマの代わりに$ xデータベースを使用した場合、パフォーマンスの違いはありますか?そして、今後どのようなソリューションを維持するほうがよいでしょうか(信頼性)?

私のデータベース/スキーマはすべて、常に同じ構造になります!

バックアップの問題(pg_dumpを使用)では、1つのデータベースと多くのスキーマを使用して、すべてのスキーマを一度にダンプする方が良いかもしれません:開発マシンにメインダンプをロードし、必要なスキーマだけをダンプして復元するのは非常に簡単です: 1つの追加手順ですが、すべてのスキーマを1つずつダンプするよりもすべてのスキーマをダンプする方が速いようです。

2012年更新

過去2年間で、アプリケーションの構造と設計は大きく変わりました。私はまだone db with many schemasアプローチを使用していますが、それでも1つのデータベースがありますバージョンごとにアプリケーションの:

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アプローチは今から非常にうまく機能しました。

私はほとんど忘れていました:私のデータベース/スキーマはすべてalwaysが同じ構造になります!

...現在、すべてのスキーマには、ユーザーのデータフローに応じて動的に変化する独自の構造があります。

129
Strae

PostgreSQLの「スキーマ」は、MySQLの「データベース」とほぼ同じです。 PostgreSQLのインストールに多くのデータベースがあると問題が発生する可能性があります。多くのスキーマを持つことは問題なく機能します。したがって、1つのデータベースとそのデータベース内の複数のスキーマを使用することは間違いありません。

99
kquinn

確かに、私はone-db-many-schemasアプローチに行きます。これにより、すべてのデータベースをダンプできますが、多くの方法で1つだけを非常に簡単に復元できます。

  1. データベース(すべてのスキーマ)をダンプし、新しいデータベースにダンプをロードし、必要なスキーマのみをダンプし、メインデータベースに復元します。
  2. スキーマを1つずつ個別にダンプします(ただし、この方法でマシンがさらに苦しむと思います-そして、500スキーマのように期待しています!)

それ以外の場合は、スキーマを複製する自動手順(テンプレートとして使用する)がないことを見て回りましたが、多くの人がこの方法を提案しています:

  1. テンプレートスキーマを作成する
  2. 複製する必要がある場合は、名前を新しい名前に変更します
  3. それを捨てなさい
  4. 名前を元に戻す
  5. ダンプを復元する
  6. 魔法は終わりました。

私はPythonでそれを行うために2行を書きました;彼らが誰かを助けることができることを望みます(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()
23
Strae

私は言う、複数のデータベースと複数のスキーマで行く:)

PostgreSQLのスキーマは、それらに精通している場合、Oracleのパッケージによく似ています。データベースはデータセット全体を区別するためのものであり、スキーマはデータエンティティに似ています。

たとえば、スキーマ「UserManagement」、「LongTermStorage」などを持つアプリケーション全体に対して1つのデータベースを作成できます。 「UserManagement」には、「User」テーブルと、ユーザー管理に必要なすべてのストアドプロシージャ、トリガー、シーケンスなどが含まれます。

データベースはプログラム全体であり、スキーマはコンポーネントです。

9
Callash

いくつかのスキーマは、いくつかのデータベースよりも軽量である必要がありますが、これを確認する参照は見つかりません。

しかし、(顧客アプリケーションの列がテーブルに追加されるようにWebアプリケーションをリファクタリングするのではなく)物事を本当に分離したい場合は、別個のデータベースを使用したい場合があります。この方法で特定の顧客のデータベースを-他の顧客を邪魔することなく。

3
Troels Arvin

PostgreSQLのコンテキストでは、複数のスキーマで1つのdbを使用することをお勧めします。可能な場合は、データベース全体ではなくスキーマ全体でUNION ALLを使用できます。そのため、データベースは別のデータベースから完全に隔離されていますが、スキーマは同じデータベース内の他のスキーマから隔離されていません。

何らかの理由で将来スキーマ間でデータを統合する必要がある場合、複数のスキーマでこれを簡単に行うことができます。複数のデータベースでは、複数のdb-connectionsが必要になり、アプリケーションロジックによって各データベースから「手動で」データを収集してマージします。

後者にはいくつかの場合に利点がありますが、主な部分については、1データベース複数スキーマアプローチの方が便利だと思います。

3
emax