m L*_*zad 5 python database-design memoization data-structures
什么是最好的数据结构缓存(保存/存储/记忆)这么多功能导致数据库.假设函数calc_regress在python中具有流动的定义:
def calc_regress(ind_key, dep_key, count=30):
independent_list = sql_select_recent_values(count, ind_key)
dependant_list = sql_select_recent_values(count, dep_key)
import scipy.stats as st
return st.linregress(independent_list, dependant_list)
Run Code Online (Sandbox Code Playgroud)
我看到应该使用什么样的表结构来存储memoized函数参数和结果在关系数据库中的答案?但是当我有大约500个功能的时候好像解决了一个功能的问题.
选项A
您可以使用链接答案中的结构,未标准化,列数 = 500 个函数中的最大参数数。还需要添加函数名称列。
然后你可以做一个SELECT * FROM expensive_func_results WHERE func_name = 'calc_regress' AND arg1 = ind_key AND arg2 = dep_key and arg3 = count,等等。
当然,这不是一个很好使用的设计。对于使用较少参数调用的同一函数,需要忽略具有空值/不匹配的列;否则你会得到多个结果行。
选项B
创建表/结构为func_name, arguments,result其中“参数”始终是 kwargs 字典或位置参数,但每个条目不混合。即使将 kwargs 字典存储为字符串,其中的键->值的顺序也是不可预测/一致的,即使它是相同的参数。因此,在转换为字符串并存储之前,您需要对其进行排序。当您想要查询时,您将使用SELECT * FROM expensive_func_results WHERE func_name = 'calc_regress' AND arguments = 'str(kwargs_dict)',其中str(kwargs_dict)是您将以编程方式设置的内容。inspect.getargspec它也可以设置为, (或)的结果inspect.getcallargs,但您必须检查一致性。
除非您提供查询的所有参数或与 部分匹配,否则您将无法对参数组合进行查询LIKE。
选项C
一路标准化:一张表func_calls为func_name, args_combo_id, arg_name_idx, arg_value。表的每一行将存储该函数调用参数的一个组合的一个参数。另一个表func_results为func_name, args_combo_id, result。您还可以进一步规范化以func_name映射到func_id.
在此例中,关键字参数的顺序并不重要,因为您将执行内部联接来选择每个参数。该查询必须以编程方式构建或通过存储过程完成,因为获取所有参数所需的联接数量由参数数量决定。上面的函数有 3 个参数,但你可能有另一个 10 个参数。arg_name_idx是“参数名称或索引”,因此它也适用于混合 kwargs + 参数。calc_regress(ind_key=1, dep_key=2, count=30)在and等情况下可能会出现一些重复calc_regress(1, 2, 30)(以及calc_regress(1, 2)count <-- 这种情况应该避免,表条目应该具有所有参数);因为args_combo_id两者的结果会有所不同,但结果显然是相同的。同样,检查模块可能在这方面有所帮助。
[编辑] PS:此外,对于func_name,您可能需要使用完全限定名称以避免包中模块之间的冲突。装饰器也可能会干扰这一点;没有deco.__name__ = func.__name__等
PPS:如果对象被传递给数据库中记忆的函数,请确保它们__str__是有用且可重复/一致的,可以存储为参数值。
这种特殊情况不需要您从数据库中的参数值重新创建对象,否则,您需要按照预期的方式进行操作__str__(但__repr__通常不会这样做):__repr__
这应该看起来像一个有效的 Python 表达式,可用于重新创建具有相同值的对象(给定适当的环境)。
| 归档时间: |
|
| 查看次数: |
296 次 |
| 最近记录: |