Postgresql:最好使用多个数据库,每个数据库有1个模式,还是1个数据库有多个模式?

时间:2009-07-20 08:45:47

标签: database database-design postgresql database-permissions

在我的问题this comment之后,我在想是否更好地使用带有X模式的1个数据库,反之亦然。

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

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

  1. 创建具有有限权限的数据库用户;
  2. 创建一个只能由之前创建的用户和超级用户(用于维护)访问的数据库
  3. 填充数据库
  4. 现在,我需要对postgresql做同样的事情(项目越来越成熟,mysql ......不能满足所有需求)

    我需要让所有数据库/模式备份独立:pg_dump在两种方式下都能很好地工作,对于可以配置为只能访问1个模式或1个数据库的用户来说是一样的。

    所以,假设你是比我更有经验的potgres用户,你认为对我的情况最好的解决方案是什么,为什么?

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

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

    Edit2 :对于备份问题(使用pg_dump),使用1 db和多个模式可能更好,一次性转储所有模式:恢复将非常简单地在dev中加载主转储机器然后转储和恢复只需要的架构:还有1个额外的步骤,但是转储所有架构似乎更快,然后逐个转储它们。

    p.s:对不起,如果我在文本中忘记了一些'W'字符,我的键盘会受到该按钮的影响;)

    2012年更新

    嗯,应用程序的结构和设计在过去的两年里发生了很大变化。 我仍在使用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
    

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

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

    从现在开始,1-db-many-schema方法对我来说非常有效,即使应用程序结构完全改变了:

      

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

    ...现在,每个模式都有自己的结构,可以改变对用户数据流的反应。

8 个答案:

答案 0 :(得分:95)

PostgreSQL“架构”与MySQL“数据库”大致相同。在PostgreSQL安装上安装许多数据库可能会出现问题;有很多架构将毫无困难地工作。因此,您肯定希望在该数据库中使用一个数据库和多个模式。

答案 1 :(得分:21)

当然,我会采用1-db-many-schemas方法。 这允许我转储所有数据库,但在很多方面很容易恢复1:

  1. 转储db(所有架构),在新数据库中加载转储,转储我需要的架构,然后在主db中恢复
  2. 逐个转储架构(但我觉得机器会受到更多这样的影响 - 而且我期待500个架构!)
  3. 否则,谷歌搜索我已经看到没有自动程序来复制架构(使用一个作为模板),但许多人建议这样:

    1. 创建模板架构
    2. 需要复制时,请使用新名称重命名
    3. 转储
    4. 重新命名
    5. 恢复转储
    6. 神奇已经完成。
    7. 我在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()
      

答案 2 :(得分:8)

我想说,使用多个数据库和多个模式:)

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

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

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

答案 3 :(得分:6)

由于这组原因,我建议不要接受已接受的答案 - 多个数据库而不是多个模式:

  1. 如果您正在运行微服务,您希望在您的“架构”之间强制无法加入,这样数据就不会纠缠在一起,开发人员也不会最终加入其他微服务的架构,并想知道为什么当其他团队进行更改时,他们的东西不再有效。
  2. 如果您的负载需要轻松,您可以稍后迁移到单独的数据库计算机。
  3. 如果您需要设置高可用性和/或复制,最好拥有彼此完全独立的单独数据库。与整个数据库相比,您不能只复制一个架构。

答案 4 :(得分:3)

许多模式应该比许多数据库更轻量级,但我找不到确认这一点的参考。

但是如果你真的想把事情分开(而不是重构web应用程序,以便在你的表中添加“costomer”列),你可能仍然想要使用单独的数据库:我断言你可以更容易以这种方式恢复特定客户的数据库 - 不会打扰其他客户。

答案 5 :(得分:2)

在postgres-context中,我建议使用一个带有多个模式的数据库,因为您可以(例如)跨模式使用UNION ALL,但不能跨数据库使用。因此,数据库实际上与另一个数据库完全隔离,而模式不与同一数据库中的其他模式隔离。如果由于某种原因 - 将来必须在模式之间整合数据,那么在多个模式上执行此操作将很容易。对于多个数据库,您需要多个数据库连接,并通过应用程序逻辑“手动”收集和合并来自每个数据库的数据。

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

答案 6 :(得分:0)

<块引用> <块引用>

使用具有多个模式的单个数据库是一种很好的方式 在 postgres 数据库中实践,因为:

  1. 在 postgres 中没有跨数据库共享任何数据。
  2. 与服务器的任何给定连接只能访问单个数据库中的数据,即连接请求中指定的数据库。

使用多个模式:

  1. 允许多个用户使用一个数据库而不会相互干扰。
  2. 将数据库对象组织成逻辑组,使其更易于管理。
  3. 第三方应用程序可以放入单独的架构中,这样它们就不会与其他对象的名称发生冲突。

答案 7 :(得分:-4)

把事情弄清楚大多数时候你想制作一些Db只读和一些读/写所以保持架构使用只读只能保留在差异Db和读/写架构在差异数据库虽然我会建议您要在一个数据库中保留MAX 25-30架构,因为您不想在数据库上为所有架构的日志创建负载

Here is one article if u want to read more