【问题标题】:Should I use multiple databases?我应该使用多个数据库吗?
【发布时间】:2010-03-09 23:32:52
【问题描述】:

我即将使用 Ruby on Rails 创建一个应用程序,我想使用多个数据库,基本上是一个会计应用程序,每个用户都有多个公司。我想为每家公司创建一个数据库

我找到了这个帖子http://programmerassist.com/article/302 但我想阅读更多关于这个问题的想法。 我必须在 MySQL 和 PosgreSQL 之间做出选择,哪个数据库可能更适合我的问题。

【问题讨论】:

    标签: ruby-on-rails database multi-tenant


    【解决方案1】:

    处理多租户应用有多种选择。

    首先,您可以为您的表格添加一个范围(正如 Chad Birch 所建议的 - 使用 company_id)。对于大多数用例来说,这很好。如果您正在处理安全/私密的数据(例如会计信息),则需要非常小心地进行测试,以确保数据保持私密。

    您可以使用多个数据库运行您的系统。您可以拥有一个为每个客户端使用数据库的应用程序,或者您实际上可以为每个客户端拥有一个单独的应用程序。为每个客户端运行一个数据库会在 Rails 中减少一点点,但它是可行的。根据您拥有的客户端数量和负载预期,我实际上建议您查看运行单个应用程序。通过对您的部署设置(capistrano、chef、puppet 等)进行一些工作,您可以使其成为一个非常简化的过程。每个客户端都在一个完全独特的环境中运行,如果某个特定客户端的负载很高,您可以将它们转出到自己的服务器上。

    如果使用 PostgreSQL,您可以使用模式做类似的事情。 PostgresQL schemas 提供了一种非常方便的方法来将您的数据与不同的客户端隔离开来。一个数据库包含一个或多个命名模式,而这些模式又包含表。您需要在迁移和部署中添加一些技巧,但它的效果非常好。

    在您的 Rails 应用程序中,您将过滤器附加到打开或关闭当前用户架构的请求。

    类似:

    before_filter :set_app
    
    def set_app
      current_app = App.find_by_subdomain(...)
      schema = current_app.schema
    
      set_schema_path(schema)
    end 
    
    
    def set_schema_path(schema)
      connection = ActiveRecord::Base.connection
      connection.execute("SET search_path TO #{schema}, #{connection.schema_search_path}")
    end
    
    def  reset_schema_path
      connection = ActiveRecord::Base.connection
      connection.execute("SET search_path TO #{connection.schema_search_path}")
    end
    

    【讨论】:

      【解决方案2】:

      有关多个数据库的答案的问题在于,它们来自对多个数据库没有需求或经验的人。第二个问题是一些数据库不允许在多个数据库之间切换,包括允许用户自己进行备份和恢复,包括扩展以将一些用户指向不同的数据服务器。这是一个有用视频的链接 http://aac2009.confreaks.com/06-feb-2009-14-30-writing-multi-tenant-applications-in-rails-guy-naor.html

      此链接将对使用 Postgresql 的 Ruby on Rails 有所帮助。

      我目前有一个多租户、多数据库、多用户(许多登录到具有不同访问级别的同一租户),并且是一个在线 SaaS 应用程序。实际上有两种应用程序,一种是会计类,另一种是银行类。两个应用程序都建立在相同的结构和方法上。客户端用户(租户)可以在该用户的登录下切换数据库。税务会计师等代理用户只能在其客户的数据库之间切换。超级用户可以切换到任何数据库。有一个数据字典,即只有一个定义表和列的地方。有全局数据和本地数据。全局数据,例如可供所有人使用的主会计科目表(只读)。本地数据是用户的数据库。新用户可以获得主数据库的克隆。有多个克隆可供选择。超级用户可以维护克隆数据库。

      问题在于它在 COBOL 中并使用 ISAM 文件并使用 CGI 方法。这样做的问题是 a) 人们认为 COBOL 已经过时,b) 获得训练有素的人员,c) 价格和 d) 在线帮助。否则它会起作用,我对此很满意。

      所以我正在研究用什么来代替它以及那是什么雷区。

      【讨论】:

        【解决方案3】:

        已经过去了,对此的决定是使用 PostgreSQL 模式,制作多租户应用程序,我有一个名为 common 的模式,用于存储相关数据。

        # app/models/organisation.rb
        class Organisation < ActiveRecord::Base
          self.table_name = 'common.organisations'
          # set relationships as usual
        end
        
        # app/models/user.rb    
        class User < ActiveRecord::Base
          self.table_name = 'common.users'
          # set relationships as usual
        end
        

        然后对于迁移,我已经通过这个出色的教程做到了这一点。 http://timnew.github.com/blog/2012/07/17/use-postgres-multiple-schema-database-in-rails/ 使用这个,这比我在其他地方看到的要好得多,甚至就像 Ryan Bates 在 railscasts 上所做的那样。

        创建新组织时,会使用该组织的子域名称创建一个新架构。我过去读到过,使用不同的模式不是一个好主意,但这取决于你正在做的工作,这个应用程序几乎没有社交组件,所以它很适合。

        【讨论】:

          【解决方案4】:

          不,您不应该使用多个数据库。

          我不太确定该给你什么建议,看来你对数据库设计有一些非常基本的误解,你可能想先了解一下数据库的基础知识,然后再继续。

          您很可能只想在表中添加“公司 ID”类型的列,以识别特定记录属于哪个公司。

          【讨论】:

          • 为什么使用多个数据库是个坏主意?
          • 我的意思是,提供数据完整性和安全性是一种非常常见的策略。
          • @Chad:告诉某人在完全不具体的情况下进行自我教育会让人觉得很无情。至少一个链接会有所帮助。话虽如此,鉴于问题缺乏细节,您的最后一段似乎是合理的,但总的来说,这是一个非常无益的答案。
          • 我明白你的意思,在关系中有 company_id 是有道理的,但问题是公司的数据与其他公司的其他数据无关,我更担心查询是否会当我有许多具有适当索引的公司时,请放慢速度。我现在对扩展不感兴趣,我知道这可能是更好的解决方案,但我会在需要时进行扩展。
          • @Boris - “但我会在需要时进行扩展”......这些话在项目开始时已经被许多人说过。当然,任何继承这个项目并试图在以后使其规模化的人所说的话会有一些不同的说法!从一开始就做好,你的应用会活得更久。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2011-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-05-08
          相关资源
          最近更新 更多