给定n个变量的昂贵函数,返回标量值:
f(x1, x2, ..., xn) = y
如果我想在关系数据库中记住这个函数,我应该使用什么样的表结构,以及适用哪种数据建模方法?
(相关但从不同角度:What kind of data model models function parameters and results?)
答案 0 :(得分:1)
在某种程度上取决于'n'的值,你可以像这样建模。假设'n'的值是137。
create table expensive_function_of_n_vars (
x1 integer not null,
x2 integer not null,
...
x137 integer not null,
primary key (x1, x2, ..., x137),
result integer not null
);
在正常情况下,我不愿意在不包含CHECK()约束的情况下存储结果,以确保它是正确的结果。在你的情况下,这可能不实用,但无论如何你应该考虑一下。
这假设每列都带有某种含义。也就是说,我假设在实际问题域中,每个列的名称都比“x3”更有意义。
例如,在您引用的文章中,OP使用“height”,“width”和“depth”。在某些应用中,这些尺寸不可互换 - 您可以明确地识别真实世界物体上的哪个尺寸是高度,即宽度,哪个是深度。 (一个例子可能是托盘上的集装箱,高度明显,宽度是叉车预计适合的边缘,深度是剩余尺寸。)在其他应用中,它们是可互换的,这意味着你'我很容易找到“重复的”主键,如{2,3,5}和{2,5,3}。在这种情况下,您可能希望将参数从最低到最高排序,并使用CHECK()约束来确保它们是有序的。
这只是直接规范化,但需要注意的是,在这种情况下,你在6NF中开始,我认为,所以没有太多事情要做。
答案 1 :(得分:1)
首先,DBMS不一定是处理memoization的最佳选择。只有当结果数量太大而无法容纳在RAM中或者结果需要在很长一段时间内保持或需要在多个(可能是并发的)客户端之间重用时,这种方法才是合理的。
对于每个函数,创建一个单独的表,其中的列对应于函数输入和结果。在输入上创建PK。
在评估功能之前(value1
,value2
,value3
...),请执行以下操作:
SELECT result
FROM function_table
WHERE
input1 = :value1
AND input2 = :value2
AND input3 = :value3
...
(:
表示绑定参数,某些DBMS可能使用不同的前缀)
通过为每个函数使用带有绑定参数的单独表和静态定制查询,您可以利用query preparation来获得更好的性能。
另外,考虑clustering the table(如果您的DBMS支持它),直接从B-Tree结构获取结果,并避免需要进行表堆查找。