给定一个返回标量值的 n 个变量的昂贵函数:
f(x1, x2, ..., xn) = y
如果我想在关系数据库中记忆这个函数,我应该使用什么样的表结构,以及应用什么样的数据建模方法?
(相关但从不同的角度:什么样的数据模型模型函数参数和结果?)
给定一个返回标量值的 n 个变量的昂贵函数:
f(x1, x2, ..., xn) = y
如果我想在关系数据库中记忆这个函数,我应该使用什么样的表结构,以及应用什么样的数据建模方法?
(相关但从不同的角度:什么样的数据模型模型函数参数和结果?)
在某种程度上取决于“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 使用“高度”、“宽度”和“深度”。在某些应用程序中,这些维度是不可互换的——您可以明确地识别现实世界对象上的哪个维度是高度,哪个是宽度,哪个是深度。(一个例子可能是托盘上的集装箱,其中高度是显而易见的,宽度是叉车预期适合的边缘,深度是剩余的尺寸。)在其他应用中,它们是可互换的,这意味着你'很容易找到像 {2, 3, 5} 和 {2, 5, 3} 这样的“重复”主键。在这种情况下,您可能希望将参数从最低到最高排序,并使用 CHECK() 约束来确保它们是有序的。
这只是简单的规范化,需要注意的是,在这种情况下,我认为你是从6NF 开始的,所以没什么可做的。
首先,DBMS 不一定是处理记忆的最佳选择。仅当结果数量太大而无法放入 RAM 中,或者结果需要在很长一段时间内持久保存或需要在多个可能并发的客户端之间重用时,这种方法才是合理的。
对于每个函数,创建一个单独的表,其中的列对应于函数输入和结果。在输入上创建一个 PK。
在评估函数(on value1
, value2
, value3
...)之前,请执行以下操作:
SELECT result
FROM function_table
WHERE
input1 = :value1
AND input2 = :value2
AND input3 = :value3
...
(:
表示绑定参数,一些 DBMS 可能使用不同的前缀)
通过为每个函数使用单独的表和带有绑定参数的静态定制查询,您可以利用查询准备来获得更好的性能。
此外,考虑对表进行聚类(如果您的 DBMS 支持),直接从 B-Tree 结构中获取结果并避免表堆查找的需要。