【问题标题】:Loading large data sets into a Rails application将大型数据集加载到 Rails 应用程序中
【发布时间】:2012-05-30 13:12:53
【问题描述】:

我正在处理数百万行数据,我想将它们作为模型加载到我的 Rails 应用程序中。我使用 MySQL 作为数据库,并且使用的是 Rails 2.3.14。

我的一位同事说,绕过 Rails ActiveRecord 系统直接向 MySQL 添加记录是不可取的。他没有具体说明,但要点是当你使用它的 ActiveRecord 系统时 Rails 会做很多“魔法”,如果你在这个系统之外输入数据,它会混淆 Rails。有人能详细说明这是否准确吗?

如果我应该通过 ActiveRecord 将数据加载到 Rails 中,我已经读到 activerecord-import 插件是完成此类工作的方式。

欢迎任何有关将大量数据加载到 Rails 中的最佳方法的反馈。

【问题讨论】:

    标签: mysql ruby-on-rails activerecord rails-models activerecord-import


    【解决方案1】:

    我能想到要考虑的六个主要项目,最后五个与 rails 'magic' 相关:

    1. 速度。这是巨大的。 Active Record,一次插入每行可能需要一秒钟。因此,对于一百万行来说,这是一百万秒 - 那是 11.5 DAYS,这将给很多人带来不好的评价!

    2. 验证。您需要确保数据库强制执行与模型/现有数据中相同的验证。

    3. 时间戳。如果您想像 rails 一样更新 created_at / updated_at ,则需要手动更新时间戳

    4. 计数器缓存。您需要手动更新计数。

    5. ActiveRecord gems 例如,如果您使用acts_as_audited 可以跟踪模型记录的数据更改,那么如果您在ActiveRecord 之外,您将无法使用该功能。

    6. 模型层的业务逻辑。 优秀的程序员尽可能将功能置于模型(或更高)层。这可能包括更新其他数据、发送电子邮件、写入日志等项目。如果不调用 ActiveRecord,则不会发生这种情况。

    【讨论】:

    • 你会推荐什么方法来加载数据?主动记录导入?
    【解决方案2】:

    直接插入 MySQL 可能会绕过模型观察器、计数器缓存以及您的应用依赖 ActiveRecord 为您执行的其他功能。如果您决定将数据直接插入 MySQL,请注意这一点,并确保您考虑了 ActiveRecord 将进行的所有更改和验证。无论您编写什么插入脚本,都应该进行相同的更改。

    示例:您有 studentsteachers 表。将记录插入students 可能需要您更新teachers.students_count 计数器缓存列 ActiveRecord 通常会为您递增。

    除此之外,您没有理由不能直接插入数据。除了这些担忧之外,任何担忧都只是毫无根据的 FUD。

    使用 ActiveRecord 的真正瓶颈是 ActiveRecord 模型对象的实例化,这非常复杂。您可能需要考虑将插入/导入脚本编写为rake 任务并使用arel(支持ActiveRecord 的低级查询接口)或像activerecord-import 这样的gem。请记住,这两种方法都将(或至少可以)跳过正常的验证、观察者、计数器缓存等,因此您仍然需要自定义逻辑来解决这个问题。

    【讨论】:

    • “这些方法将(或至少可以)跳过正常的验证、观察者、计数器缓存等,因此您仍然需要自定义逻辑来解决这个问题。”那么相对于 SQL 导入,使用 activerecord-import 有什么好处呢?
    • @babonk 优点是您仍然可以使用 Arel、模型范围和 Rails 拥有的其他很酷的查询工具,但避免了 AR 模型实例化的损失。如果您需要为某些模型实例化以运行验证或回调或您可以为您需要的模型执行的任何操作。它只是工具带中的一个工具,与构建完美的 sql 导入文件或您想到的任何其他 SQL 导入方法相比,它可能会为您节省一些时间。
    【解决方案3】:

    您不应该直接加载它有几个原因。其中一些可能适用于您,也可能不适用于您。

    数据验证 -- 您正在加载尚未验证的数据。您的 rails 应用程序可能对加载的数据做出了某些假设。此外,未经验证的数据在您的应用程序中运行时可能会引发一些有趣的问题。

    数据操作——这在某种程度上与数据验证有关,但如果您正在进行任何类型的数据操作(在网络上的数据输入和插入数据库之间),您至少需要重新创建这种操作当你上传它时。

    总的来说,这可能不是最好的主意,但这并不是因为 Rails 中的“魔法”,而是因为您的数据内置了假设,即您不会重新创建直接转储。

    【讨论】:

      猜你喜欢
      • 2017-11-16
      • 2013-11-30
      • 2014-03-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-08-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多