【问题标题】:Speed: Store aggregate values in database or calculate with Jinja?速度:在数据库中存储聚合值或使用 Jinja 计算?
【发布时间】:2017-04-26 11:57:28
【问题描述】:

语言:Python

数据库:SQLite

使用:Flask、SQLAlchemy ORM


我的问题本身可能有点矫枉过正,但我​​很好奇。

我在 SQLAlchemy Table 中有列,其中包含我需要对其执行数学运算、显示聚合值或计算值的某些值。

假设:

第 1 列:0

第 2 列:5

第 3 列:2

第 4 列:6

在 HTML 表格中,我需要依赖这些值来计算和显示对它们的算术运算结果。

示例:(Column 1 + Column 2 + Column 3 / Column 6)* 100

我是计算这些数字并将它们存储在我的 SQLite 数据库的一个新列中(使用 SQLAlchemy),还是使用 Jinja2 即时计算它们?

【问题讨论】:

  • 我会使用 Jinja2 来计算它,或者将结果存储在缓存中
  • 非常有趣。我知道什么是缓存(我认为),但是缓存如何在 Python/Flask 程序中工作?
  • 它的工作方式类似于哈希表。首先计算值,然后以与使用哈希表相同的方式将其存储在缓存中,然后可以通过键值对执行查找。你可以用谷歌搜索 memcache 并将其添加到你的项目中。

标签: python database sqlite jinja2 flask-sqlalchemy


【解决方案1】:

对于任何优化问题,实际上都没有单一的校正解决方案。您必须通过测试找出最佳解决方案。您的案例是对时间(速度)的优化,因此我们应该查看内存(权衡)或数据是如何持久化和访问的。以下是您的数据通过的层:

磁盘 -> SQLite 驱动程序 -> Python SQLite DBAPI -> SQLAlchemy -> Jinja

排除磁盘(因为您选择的数据库在处理物理存储优化方面并没有真正的技巧 - 毕竟它是一个文件)并排除 DBAPI 层(它与 SQLAlchemy 集成很好,您没有SQLite 的 DBAPI 驱动程序之间有很多选择),以下是您计算每一层中的列的可能方法:

  1. SQLite 驱动程序 - 您可以在 SQLite 中 create a view 计算列

    • 上层看到的视图就像一张桌子
    • 可以更改上层但保持相同的定义
    • 如果不借助删除和重新创建视图,就无法动态修改计算
    • 还不能memoize计算
    • 视图是只读的 - 围绕它构建 ORM 包装器毫无意义
    创建视图 view_name ( 列_1, 列_2, column_3_you_can_rename_columns_here, 列_6, 列_X) 作为选择 列_1, 列_2, 列_3, 列_6, (column_1 + column_2 + column_3 / column_6) * 100.0 FROM 表名
  2. SQAlchemy - 可以将计算列添加到表类定义中

  3. Jinja - 也可以在 Jinja 中进行计算

    • 在这一层完成的计算不容易传递到前面的层 - 难以持久化到数据库
    • 可能不是最有效的

根据经验,您通常会通过在数据库级别进行预先计算来获得最佳结果,因为计算是在一次将数据从磁盘提取到内存时完成的。但是,您选择的数据库将您的选择限制为主要在 Python 级别进行优化。您需要使用timeit 测试哪种方法最适合您的用例。

除非您的数据(输入列)具有频繁重复的值,否则记忆化可能对您没有帮助。请注意premature optimization is the root of all evil

【讨论】:

  • 多么好的答案,谢谢!。只是跟进您的经验:对我来说,这听起来是更简单、更好的解决方案,但我得到的建议是:“冗余很糟糕”。
猜你喜欢
  • 1970-01-01
  • 2018-04-21
  • 1970-01-01
  • 2023-03-22
  • 1970-01-01
  • 2023-03-22
  • 2014-04-11
  • 2021-08-05
  • 1970-01-01
相关资源
最近更新 更多