Postgresql:使用多个数据库(每个具有一个模式)还是使用多个数据库(具有多个模式)会更好?

在对我的问题之一发表评论之后,我在想如果使用1个带有X模式的数据库更好,反之亦然。

我的情况:我正在开发一个networking应用程序,当人们注册时,我创build(实际)一个数据库(不,它不是一个社交networking:每个人都必须能够访问自己的数据,而不会看到其他用户的数据)。

这就是我用于以前版本的应用程序(仍然在mysql上运行)的方式:通过plesk API,对于每个注册,我都这样做:

  1. 创build具有有限权限的数据库用户;
  2. 创build一个可以被上一个创build的用户和超级用户访问的数据库(用于维护)
  3. 填充数据库

现在,我需要做同样的postgresql(该项目正在成熟和MySQL ..不满足所有的需求)

我需要使所有的数据库/模式备份独立:pg_dump完美地以两种方式工作,对于可以configuration为只访问1个模式或1个数据库的用户来说,pg_dump是完全相同的。

所以,假设你的用户比我更有经验,那么你认为最适合我的情况是什么?为什么?

使用$ x db而不是$ x schemas会有性能差异吗? 未来维护什么解决scheme会更好(可靠性)?

编辑 :我差点忘了:我所有的数据库/模式将始终具有相同的结构!

编辑2 :对于备份问题(使用pg_dump),使用1分贝和许多模式,一次转储所有模式可能会更好:恢复将是非常简单的在开发机器中加载主转储,然后转储和恢复所需的架构:还有一个额外的步骤,但是倾销所有的模式似乎更快,然后一个接一个地抛弃它们。

ps:对不起,如果我在文本中忘记了一些“W”字符,我的键盘遭受了这个button;)

更新2012年

那么最近两年的应用程序结构和devise就变得如此之多。 我仍然使用1 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 

对于备份,定期转储每个数据库,然后在dev服务器上移动备份。

我也使用PITR / WAL备份,但是,正如我之前所说,它不可能一次恢复所有的数据库 ..所以它可能会被解雇今年(在我的情况是不是最好的办法)。

从现在开始,即使应用程序结构完全改变,1-db-many-schema方法对我来说效果也不错:

我差点忘了:我所有的数据库/模式将始终具有相同的结构!

…现在,每个模式都有自己的结构,对用户数据stream作出反应。

PostgreSQL的“模式”与MySQL的“数据库”大致相同。 PostgreSQL安装有许多数据库可能会出现问题; 有许多模式将毫不费力地工作。 所以你一定要在数据库中使用一个数据库和多个模式。

当然,我会采取1-db-many-schemas方法。 这使我可以转储所有的数据库,但很容易以很多方式恢复:

  1. 转储数据库(所有模式),加载转储在一个新的数据库,转储只是我需要的模式,并恢复回主数据库
  2. 分别转储模式,但是我认为机器会受到更多的影响,而且我预计会有500个模式!

否则,search一下我已经看到没有自动过程来复制架构(使用一个作为模板),但许多人build议这样:

  1. 创build一个模板模式
  2. 需要复制时,用新名称重命名
  3. 转储它
  4. 重新命名它
  5. 还原转储
  6. 魔术完成了。

我已经写了2行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] #Temp 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 previus 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() 

我会说,去与多个数据库和多个架构:)

postgres中的模式很像Oracle中的包,以防您熟悉这些包。 数据库旨在区分整组数据,而模式更像是数据实体。

例如,可以为模式为“UserManagement”,“LongTermStorage”等的整个应用程序创build一个数据库。 然后,“用户pipe理”将包含“用户”表,以及用户pipe理所需的所有存储过程,触发器,序列等。

数据库是整个程序,模式是组件。

许多模式应该比许多数据库更轻量级,尽pipe我找不到可以证实这一点的参考。

但是,如果你真的想保持独立的东西(而不是重构Web应用程序,以便将“costomer”列添加到表中),那么可能仍然需要使用单独的数据库:我断言你可以更容易地恢复这样一个特定的客户数据库 – 而不会打扰其他客户。

在postgres上下文中,我build议使用一个数据库与多个模式,你可以(例如)跨模式的UNION ALL,但不跨数据库。 出于这个原因,数据库实际上完全与另一个数据库隔离,而模式不能与同一数据库中的其他模式隔离。 如果由于某种原因,将来必须跨数据模式整合数据,那么通过多个模式就可以轻松实现这一点。 对于多个数据库,您将需要多个数据库连接,并通过应用程序逻辑“手动”收集和合并来自每个数据库的数据。

后者在某些情况下具有优势,但对于主要部分,我认为单数据库多模式方法更有用。

清除事情首先大部分时间你想做一些Db只读和一些读/写因此保持架构用作只读可以保持差异Db和读/写架构在差异数据库中,虽然我build议你保持MAX 25-30架构在一个数据库中,因为您不想在数据库上为所有架构的日志创build负载

这是一篇文章,如果你想阅读更多