0

スカラー値を返す n 変数の高価な関数があるとします。

f(x1, x2, ..., xn) = y

リレーショナル データベースでこの関数をメモ化したい場合、どのようなテーブル構造を使用すればよいですか? また、どのデータ モデリング手法を適用しますか?

(関連しているが別の角度から:関数のパラメーターと結果をモデル化するデータ モデルの種類は? )

4

2 に答える 2

1

まず第一に、メモ化を処理するのに DBMS が必ずしも最適な選択であるとは限りません。このアプローチは、結果の数が大きすぎて RAM に収まらない場合、または結果を長期間保持する必要がある場合、または複数の (場合によっては同時の) クライアント間で再利用する必要がある場合にのみ正当化されます。

関数ごとに、関数の入力と結果に対応する列を含む個別のテーブルを作成します。入力に ​​PK を作成します。

関数 (on value1value2value3...) を評価する前に、次のことを行います。

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

(:はバインドされたパラメーターを示します。一部の DBMS では異なるプレフィックスを使用する場合があります)

  • 結果が得られたら、それを使用します。関数は以前に評価されており、今回は評価をスキップできます。
  • 結果が得られない場合 (ゼロ行など)、関数を評価し、後で再利用するために入力と結果を保存します。この INSERT をバックグラウンド スレッドで実行することを検討してください。そうすれば、データベースを待たずにメイン スレッドで結果を使用することができます。

個別のテーブルと、関数ごとにパラメーターがバインドされた静的なカスタマイズされたクエリを使用することで、クエリの準備を利用してパフォーマンスを向上させることができます。

また、B-Tree 構造から直接結果を取得し、テーブル ヒープ ルックアップの必要性を回避するために、テーブルのクラスタリングを検討してください (DBMS がサポートしている場合)。

于 2012-06-22T00:15:20.377 に答える
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 は「高さ」、「幅」、および「深さ」を使用しています。一部のアプリケーションでは、これらの寸法を交換することはできません。実際のオブジェクトのどの寸法が高さで、どの寸法が幅で、どの寸法が奥行きであるかを明確に識別できます。(1 つの例として、パレット上の輸送用コンテナが考えられます。高さは明白で、幅はフォークリフトが収まると予想される端であり、深さは残りの寸法です。) 他のアプリケーションでは、それらは交換可能です。 {2, 3, 5} や {2, 5, 3} のような「重複した」主キーを見つける可能性があります。そのような場合、引数を最低から最高の順に並べ、CHECK() 制約を使用してそれらが順序付けられていることを確認することができます。

これは単純な正規化にすぎませんが、この場合は 6NFから開始しているので、やるべきことはあまりないと思います。

于 2012-06-21T23:14:15.230 に答える