Rails 5 Active Record-是否可以将表保留在内存中? [英] Rails 5 Active Record - is it possible to keep a table in memory?

查看:168
本文介绍了Rails 5 Active Record-是否可以将表保留在内存中?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果我们有一个包含相对静态数据的小表,是否有可能在应用启动时将Active Record加载到其中,而不必再为这些数据访问数据库?

If we have a small table which contains relatively static data, is it possible to have Active Record load this in on startup of the app and never have to hit the database for this data?

请注意,理想情况下,我希望此数据可以从与之有关系的其他模型中进行联接。

Note, that ideally I would like this data to be join-able from other Models which have relationships to it.

一个示例可能是一个列表带有电话号码前缀的国家/地区-此列表不太可能更改,如果更改,则管理员可以更改。其他表可能与此相关(例如,假设某个用户参考了该国家/地区,我们可能要查找该国家/地区的电话前缀)。

An example might be a list of countries with their telephone number prefix - this list is unlikely to change, and if it did it would be changed by an admin. Other tables might have relationships with this (eg. given a User who has a reference to the country, we might want to lookup the country telephone prefix).

我看到了一个类似的问题此处,但它已有6年历史了,指的是Rails 2,而我正在使用Rails 5,也许从那时起就引入了一些东西。

I saw a similar question here, but it's 6 years old and refers to Rails 2, while I am using Rails 5 and maybe something has been introduced since then.

首选的解决方案是:


  1. 内置的Rails / ActiveRecord功能可在启动时加载一次表,并且如果随后加载了其他与缓存表有关系的记录,则自动链接到缓存的对象(即手动将MyModel.all缓存在某个地方是不够的,因为仍然可以通过查询数据库来加载关系。)

  2. 执行上述操作的维护库。

  3. 如果两种方法均不可用,我想一种替代方法是将静态数据集定义为内存中的枚举/散列或类似名称,并将散列键保留在与此数据有关系的记录上,并在这些模型上定义方法,以使用散列中的对象使用存储在散列中的键进行查找数据库。尽管这似乎很手动...


潜在解决方案还需考虑的另一件事-手动解决方案(3)还需要自定义控制器和路由,以便可以通过API访问此类数据。理想情况下,最好有一个解决方案,其中可以根据需要使用诸如脚手架之类的标准Rails机制通过RESTful API(只读-只是GET)提供此类数据,而无需过多的人工干预。

One other thing to consider with potential solutions - the manual solution (3) would also require custom controllers and routes for such data to be accessible over an API. Ideally it would be nice to have a solution where such data could be offered up via a RESTful API (read only - just GET) if desired using standard rails mechanisms like Scaffolding without too much manual intervention.

推荐答案

我认为您可能过于轻视简单 /手动方法。

I think you may be discounting the "easy" / "manual" approach too quickly.

写作将数据存储到ruby哈希/数组并不是一个坏主意。

Writing the data to a ruby hash / array isn't that bad an idea.

如果您想使用CRUD支架,为什么不使用标准的Rails模型/控制器生成器呢?在数据库中存储一些静态数据真的很糟糕吗?

And if you want to use a CRUD scaffold, why not just use the standard Rails model / controller generator? Is it really so bad to store some static data in the database?

第三个选择是将数据以某种序列化格式存储到文件中,然后在应用程序运行时读取此内容并构造ActiveRecord对象。让我举一个例子:

A third option would be to store your data to a file in some serialized format and then when your app loads read this and construct ActiveRecord objects. Let me show an example:

data.yml

---
- a: "1"
  b: "1"
- a: "2"
  b: "2"

这是一个包含哈希数组的YAML文件;您可以使用以下命令构造这样的文件:

This is a YAML file containing an array of hashes; you can construct such a file with:

require 'yaml'
File.open("path.yml", "w") do |f|
  data = [
    { "a" => "1", "b" => 1 },
    { "a" => "2", "b" => 2 }
  ]
  f.write(YAML.dump(data))
end

然后要加载数据,您可以在 config / initializers / 中创建一个文件(此处的所有内容都会由rails自动加载):

Then to load the data, you might create a file in config/initializers/ (everything here will be autoloaded by rails):

config / initializers / static_data.rb

require 'yaml'

# define a constant that can be used by the rest of the app
StaticData = YAML.load(File.read("data.yml")).map do |object|
  MyObjectClass.new(object)
end

避免写数据库 MyObjectClass 的迁移(当它实际上没有存储在数据库中时),可以为属性使用 attr_accessor 定义:

To avoid having to write database migrations for MyObjectClass (when it's not actually being stored in the db) you can use attr_accessor definitions for your attributes:

class MyObjectClass < ActiveRecord::Base
  # say these are your two columns
  attr_accessor :a, :b
end

只需确保不要运行保存删除或<$在此模型上进行c $ c> update (除非您对这些方法进行monkeypatch)。

just make sure not to run stuff like save, delete, or update on this model (unless you monkeypatch these methods).

如果您希望拥有REST / CRUD端点,则需要从头开始编写它们,因为现在更改数据的方式有所不同。
您基本上需要在3个步骤中进行任何更新:

If you want to have REST / CRUD endpoints, you'd need to write them from scratch because the way to change data is different now. You'd basically need to do any update in a 3 step process:


  1. 将数据从YAML加载到Ruby对象中list

  2. 更改Ruby对象列表

  3. 将所有内容序列化为YAML并保存。

所以您可以看到您并不是在这里进行增量更新。您可以使用JSON而不是YAML,但也会遇到同样的问题。使用Ruby的内置存储系统PStore,您可以单独更新对象,但是将SQL用于生产Web应用程序是一个更好的主意,并且将使事情变得更加简单。

So you can see you're not really doing incremental updates here. You could use JSON instead of YAML and you'd have the same problem. With Ruby's built in storage system PStore you would be able to update objects on an individual basis, but using SQL for a production web app is a much better idea and will honestly make things more simple.

除了这些序列化数据选项之外,还有关键值存储服务器将数据存储在内存中。像Memcached和Redis这样的东西。

Moving beyond these "serialized data" options there are key-val storage servers store data in memory. Stuff like Memcached and Redis.

但是回到我先前的观点,除非您有充分的理由不使用SQL,否则只会使事情变得更加困难。

But to go back to my earlier point, unless you have a good reason not to use SQL you're only making things more difficult.

这篇关于Rails 5 Active Record-是否可以将表保留在内存中?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆