Rails 6.0最近分享了其惊人的增强功能,尽管大多数人会认为这些是功能升级。
在我看来,两者都是正确的,因为在rails 6.0之前,多个数据库的实际状态甚至不被认为是一个已完成的功能。
所以,让我们深入了解一下Rails < 6的状态!Rails 6引入的变化和它目前的路线图。
Rails 5状态
ActiveRecord支持多个数据库,但Rails < 6并没有提供管理这些数据库的方法。如前所述,你需要以真正的手工方式处理一切(是的,一切),必须为seeds,db:prepare,db:migrate 等创建自己的任务。
你还需要创建一种生成器来处理你的二级数据库迁移,遵循惯例。最后(好像你做的自定义工作还不够多),你需要创建一个初始化器来配置你与新数据库的连接。
所以,ActiveRecord确实支持多个数据库,但它是一个完整的、真正的混乱,除非绝对必要,否则你应该避免。
Rails 6.0状态
新东西
- 多个主数据库和每个数据库的副本。
这很了不起,因为现在你可以在你的database.yml ,像这样轻松地配置它:
development:
primary:
database: my_primary_database
user: root
adapter: sqlite3
primary_replica:
database: my_primary_database
user: root_readonly
adapter: sqlite3
replica: true
animals:
database: my_animals_database
user: animals_root
adapter: sqlite3
migrations_paths: db/animals_migrate
animals_replica:
database: my_animals_database
user: animals_readonly
adapter: sqlite3
replica: true
看看你如何为每个数据库定义你的迁移路径,以及你如何有能力使用多个适配器(仍在为这个假设进行POC工作)。
一个用这个迁移的例子是:rails g migration CreateCats name:string --database animals ,有这样的输出:
Running via Spring preloader in process 97210
invoke active_record
create db/animals_migrate/20200819181625_create_cats.rb
- 为你正在使用的模型自动切换连接。
你只需要在你的中间件中激活它以实现自动切换:
config.active_record.database_selector = { delay: 2.seconds }
config.active_record.database_resolver = ActiveRecord::Middleware::DatabaseSelector::Resolver
config.active_record.database_resolver_context = ActiveRecord::Middleware::DatabaseSelector::Resolver::Session
你也可以手动决定你的连接上下文:
ActiveRecord::Base.connected_to(role: :reading) do
# all code in this block will be connected to the reading role
end
- 根据HTTP动词和最近的写入量,在主站和副本之间自动切换:
正如我们在Rails中所习惯的那样,这也是标准化的。
"如果应用程序收到一个POST、PUT、DELETE或PATCH请求,应用程序将自动写到主站。在写完后的指定时间内,应用程序将从主服务器上读取。
对于一个GET或HEAD请求,应用程序将从副本中读取,除非最近有一个写入。
- 用于创建、删除、迁移和与多个数据库交互的Rails任务:
第一个大的评论,通常的rails db:create ,现在会创建两个数据库,所以通常的rails db:migrate ,也会迁移两个数据库。
你需要指定你想使用哪个数据库,比如rails db:create:primary 或rails db:migrate:secondary ,如果你只想修改一个。
所以,对于你的自定义任务,你可能还需要指定你要使用的数据库。
待定的任务
- 对于Sharding来说,现在有一些宝石来完成这个任务,所以在集成到Rails上之前,我们应该继续使用宝石(没有真正的交易)。
- 当跨集群连接时,Rails指出。"应用程序不能跨数据库连接。Rails 6.1将支持使用has_many关系和创建2个查询,而不是连接,但Rails 6.0将要求你手动将连接分割成2个选择。"
所以,我们只需要等待Rails6.1!
- 负载平衡复制似乎是一个有趣的功能,我希望能看到即将到来的这方面的消息。
- 对于多个数据库的模式缓存的转储,它指出。"如果你使用模式缓存和多个数据库,你需要写一个初始化程序,从你的应用程序中加载模式缓存。这不是我们能在Rails 6.0中及时解决的问题,但希望能在未来的版本中很快解决这个问题"
所以,这似乎是一个在即将到来的版本中要解决的琐碎问题。
Rails 6.1的未来状态
正如你可能知道的,Rails 6.1就快到了,所以,我将仔细检查一下这个新版本中所说的要发布的内容,以及实际要发布的内容。
这里有一些不错的公开PR,现在:
所以,总结起来就是:
- Sharding现在是一个WIP的东西,我们可能希望在Rails 6.1中看到它的存在。
- 仍然在等待跨集群的连接(或者我在评论中错过了)。
- 还在等待负载均衡。
- 模式缓存现在是一个东西
一些个人想法
我是一个非关系型数据库的超级粉丝,所以,我很想看到一些MongoDB+Postgres的混合版本,比如说。随着引入的变化,我想我们很快就能找到一种方法来正确地使用它。
我的疑惑是:"ActiveRecord应该支持非关系型数据库吗?"或者 "在ActiveRecord之外有更多的轨道工作吗?"