Ruby active_record 多数据库链接问题求助

lb563 · 2012年07月27日 · 最后由 zw963 回复于 2012年07月28日 · 4870 次阅读

背景: 用 rails 链接多个数据库,让一部分 model 链接数据库"dev1"让另一部分 model 链接数据库"dev2" 我之前的做法是:在需要链接"dev1"数据库的 model 中使用方法"establish_connection :dev1" ,这样使用是 ok 的. 但是当你的 model 数量很多的时候,你会发现 rails 会在 mysql 建立很多链接 (你可以使用 show processlist来查看 mysql 的进程信息) 这样消耗的资源太多了,于是想找一个方法来处理这种情况。现在我的思路是: 让一个类 (Dev1) 继承 "ActiveRecord::Base" 然后调用方法:"establish_connection :dev1" 使之链接到数据库"dev1" 让需要链接数据库"dev1"的 model 再继承 Dev1 类,这样的话即使有上百个 model 也只会建立两个 mysql 链接

实验结果: 在 Dev1Sub, Dev2Sub model 中调用方法"count" 可以输出数量 在 Dev1Sub, Dev2Sub model 中调用方法"first" 会出现异常 #Mysql2::Error: Table 'wow_world.dev1s' doesn't exist: SHOW FULL FIELDS FROM dev1s (ActiveRecord::StatementInvalid)

#encoding: utf-8
require "active_record"
require "pry"
require "erb"

#数据库配置
Conf = <<-EOF
dev1:
  adapter: mysql2
  encoding: utf8
  database: wow_world
  username: root
  password: 
  socket: /tmp/mysql.sock
  port:  3306
  host:  '127.0.0.1'

dev2:
  adapter: mysql2
  encoding: utf8
  database: world
  username: root
  password: 
  socket: /tmp/mysql.sock
  port:   3306
  host:  '127.0.0.1'
EOF

#定义一个共用类,用于链接指定的数据库 dev1
class Dev1 < ActiveRecord::Base
  self.configurations = YAML::load(ERB.new(Conf).result)
  establish_connection :dev1
end

#定义一个共用类,用于链接指定的数据库 dev2
class Dev2 < ActiveRecord::Base
  self.configurations = YAML::load(ERB.new(Conf).result)
  establish_connection :dev2
end

#定义些子类用于实现需要和功能
class Dev1Sub < Dev1
    self.table_name ="item"
end

class Dev2Sub < Dev2
    self.table_name ="item"
end

class Tmp < ActiveRecord::Base
    self.configurations = YAML::load(ERB.new(Conf).result)
  establish_connection :dev1
    self.table_name = "item"
end
#执行
puts Dev1Sub.count          #=> 49838
puts Dev2Sub.count          #=> 993

puts Tmp.first.id           #=> 1
puts Dev1Sub.first.id   #Mysql2::Error: Table 'wow_world.dev1s' doesn't exist: SHOW FULL FIELDS FROM `dev1s` (ActiveRecord::StatementInvalid)

请教各们大牛们: 为什么类 "Dev1Sub" 能使用方法 "count" 而不能调用方法" first" 呢?

我的猜想: 既然能调用到方法 count 说明类"Dev1Sub,Dev2Sub"在数据库中找到对应的数据库表 并具有操作这张表的各种方法但是不解的是为什么不能调用类的"first"方法呢?

自己回答一下吧: 在 Dev1,Dev2 类中加入"self.abstract_class = true" #=> 表示这个模型类不会与库中的任何表有关系,也就是一个抽象的类。

匿名 #2 2012年07月27日

哇,好高级,学习了,一直想,大数据量用分库分表,不过一直没在 rails 上试过。暂时还没碰到这样的需求的项目。。。期待 ing

长见识了。佩服楼主的研究精神。

我通过哈希的方式,使用过 establish_connection, 但是这种 Rails 默认的方式还真没用过。代码收录啦。谢谢。

需要 登录 后方可回复, 如果你还没有账号请 注册新账号