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


147

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

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

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


「私のデータベース/スキーマはすべて同じ構造になります!」それらはすべて同じ構造を持っているということですか?または決して?
Osama Al-Maadeed 2009

申し訳ありませんが、はい、それらはすべて同じ構造を永久に持ちます。1つ変更すると、すべて変更されます;)
Strae

1000の顧客がいる場合、それは1000のスキーマを更新する必要があることを意味しますか?
ジョシュアパルトギ

@jpartogi:はい。ただし、データではなくテーブル構造のみを更新する必要があります。
Strae

それで、最終的に何のために行きましたか?ただし、クエリなどのパフォーマンスはテーブルスペースで制御できますが、スキーマによって、マルチデータベースとマルチスキーマのパフォーマンスが同等になり、WALログに影響が出ますか???
Kapil

回答:


113

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


33
この。Postgresでは、データベース間でクエリを実行することはできません。
matt b

81
「PostgreSQLインストールに多くのデータベースがあると、問題が発生する可能性があります」-明確にしてください。それは一般的に、またはこの特定の場合に問題がありますか、そしてなぜですか?
akaihola 2009

33
「データベースで複数のスキーマを使用する最も一般的な使用例は、顧客ごとに独自のスキーマを持つサービスとしてのソフトウェアアプリケーションを構築することです。この手法は説得力があるように見えますが、多くの事例が発生しているため、これは推奨されません。 。操作上の問題例えば、スキーマのも、適度な数(> 50)は、深刻な「Herokuののデータベースのスナップショットツールのパフォーマンスに影響を与える可能性がdevcenter.heroku.com/articles/heroku-postgresql
ニール・マクギガン

16
@NeilMcGuigan:興味深いことに、それはkquinnの(受け入れられた)回答からの反対の結論のようです。
カーボケーション

8
ただし、1つのデータベースに多数のスキーマがあると、それらの単一のスキーマをダンプすることは事実上不可能になります。3000を超えるスキーマを持つ単一のpostgresデータベースを実行していますが、単一のスキーマをダンプしようとすると、pg_dumpがメモリ不足エラーで失敗します。これは、I 3000データベースを使用した場合とは異なるのではないかと思います。
町筋2017

27

間違いなく、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()

14

私は言うでしょう、複数のデータベースと複数のスキーマを使います:)

PostgreSQLのスキーマは、慣れている場合、Oracleのパッケージとよく似ています。データベースは、データセット全体を区別することを目的としていますが、スキーマはデータエンティティに似ています。

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

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


4
...そして、スキーマ内に1つのデータベースを作成します。ええと...信頼できる方法のように思われません...そしてパフォーマンスはどうですか?そして、私のアプリケーションのコードはどうですか(phpとpythonになります)?非常に多くのスキーマ..
Strae

7
@Strae:私はこれを次のように読んでいます。各顧客にはデータベースcustomer1_database、customer2_databaseがあり、それらのデータベース内にuser_schema、documents_schemaがあります。
frankhommers 16

6

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

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

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


4

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

しかし、本当に個別に保持したい場合は(「顧客」列がテーブルに追加されるようにWebアプリケーションをリファクタリングするのではなく)、別のデータベースを使用することをお勧めします。特定の顧客のデータベースをこの方法で-他の顧客に影響を与えることなく。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.