应该使用什么样的表结构来存储关系数据库中的记忆函数参数和结果



给定一个返回标量值的 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。

在计算函数之前(在value1value2value3...),执行以下操作:

SELECT result
FROM function_table
WHERE
    input1 = :value1
    AND input2 = :value2
    AND input3 = :value3
    ...

:表示绑定参数,某些 DBMS 可能使用不同的前缀)

  • 如果得到结果,请使用它。该函数之前已评估过,这次可以跳过评估。
  • 如果没有结果(即零行),请评估函数并存储输入和结果以供以后重用。请考虑在后台线程上执行此 INSERT,以便您可以继续在主线程上使用结果,而无需等待数据库。

通过使用单独的表和静态定制查询以及每个函数的绑定参数,您可以利用查询准备来提高性能。

此外,请考虑对表进行聚类分析(如果您的 DBMS 支持它),以便直接从 B 树结构获取结果,并避免需要表堆查找。

最新更新