语言:Python
数据库:SQLite
使用:Flask、SQLAlchemy ORM
我的问题本身可能有点过分了,但我很好奇。
我在 SQLAlchemy 中有列Table
其中包含我需要执行数学运算的某些值,以显示聚合值或计算值。
我们假设:
Column 1: 0
Column 2: 5
Column 3: 2
Column 4: 6
在 HTML 表中,我需要依赖这些值来计算并显示对它们进行算术运算的结果。
例子: (Column 1
+ Column 2
+ Column 3
/ Column 6
) * 100
我是否计算这些数字并将它们存储在 SQLite 数据库的新列中(使用 SQLAlchemy),或者使用即时计算它们Jinja2 http://jinja.pocoo.org/docs/dev/templates/#math?
对于任何优化问题,实际上都没有单一的校正解决方案。您必须通过测试找出最佳解决方案。您的案例是时间(速度)的优化,因此我们应该考虑内存(权衡)或数据的持久化和访问方式。以下是数据经过的层:
磁盘 -> SQLite 驱动程序 -> Python SQLite DBAPI -> SQLAlchemy -> Jinja
排除磁盘(因为您选择的数据库在处理物理存储优化方面并没有真正的技巧 - 毕竟它是单个文件)并排除 DBAPI 层(它与 SQLAlchemy 集成很好,并且您没有太多的SQLite 的 DBAPI 驱动程序之间的选择),以下是计算每一层中的列的可能方法:
-
SQLite 驱动程序 - 您可以创建一个视图 https://sqlite.org/lang_createview.html在 SQLite 中计算列
- 上层将视图视为表格
- 可以更改上层但保持相同的定义
- 如果不删除并重新创建视图,则无法动态修改计算
- Cannot memoize https://en.wikipedia.org/wiki/Memoization计算尚未
- 视图是只读的 - 围绕它构建 ORM 包装器毫无意义
CREATE VIEW view_name (
column_1,
column_2,
column_3_you_can_rename_columns_here,
column_6,
column_X)
AS SELECT
column_1,
column_2,
column_3,
column_6,
(column_1 + column_2 + column_3 / column_6) * 100.0
FROM table_name
-
SQLAlchemy - 计算列可以添加到您的表类定义中
- 可用于将计算值保留/保存为数据库中的实际列的选项
- 可以动态更改计算,就像在 Python 层中一样
- 可以记住计算结果
- 对于持久计算列,请参阅:https://stackoverflow.com/a/4284191/1027422 https://stackoverflow.com/a/4284191/1027422
- 对于简单的仅 Python(不保存到数据库)计算列,请参阅:http://docs.sqlalchemy.org/en/latest/orm/mapped_sql_expr.html http://docs.sqlalchemy.org/en/latest/orm/mapped_sql_expr.html
- 如何缓存或记忆计算,请参阅 lru_cache 部分https://docs.python.org/3/library/functools.html https://docs.python.org/3/library/functools.html
-
Jinja - 也可以在 Jinja 中进行计算
- 在这一层完成的计算不容易传递到前面的层 - 难以持久化到数据库
- 可能不是最有效的
根据经验,通过在数据库级别进行预计算通常会获得最佳结果,因为计算是在数据一次性从磁盘提取到内存时完成的。但是,您对数据库的选择限制了您只能在 Python 级别进行优化。您需要使用以下方法来测试哪种方法最适合您的用例timeit https://docs.python.org/2/library/timeit.html.
除非您的数据(输入列)具有频繁重复的值,否则记忆可能对您没有帮助。但请注意过早的优化是万恶之源 http://slides.com/pythonph/pyconph-2015-root-of-all-evil#/25.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)