2

私は自分が書いたMathematicaスクリプトの各実行に関する情報を保存するデータベース(SQLite)の構築に取り組んでいます。スクリプトはいくつかの入力パラメーターを受け取るので、私のDBには、(他の列の中でも)各パラメーターの列を持つテーブルがあります。

入力パラメータの一部は、数値のリストです。これらを保存するための私の最初の考えは、この質問に対する受け入れられた回答で説明されているように、ジャンクションテーブルを使用することです。しかし、私は通常、いくつかの異なる実行に同じリストを使用します。特定のリストがすでにデータベースにあるかどうかを調べるにはどうすればよいですか。そのため、IDを再保存するのではなく、再利用できますか?

コメントで述べられている制約:

  • リストの長さに明示的な上限はありませんが、実際には1から約50の範囲です。
  • 個別のリストの数は少なく、10のオーダーになります。
  • 私は実際に3つのリストパラメータを持っています。それらのうちの2つについては、リスト内の値は非負の倍精度浮動小数点数です。3番目の場合、値はそのような数値のペアです。
  • 重複するエントリはありません。(これらはより正確に設定されているため、重複や順序は関係ありません)
  • リスト要素をソート順に並べることが簡単にできます。

例:私のテーブルがこのように設定されているとします

CREATE TABLE jobs (id INTEGER PRIMARY KEY, param1 REAL, param2_id INTEGER);
CREATE TABLE param2 (param2_id INTEGER PRIMARY KEY, value REAL);

スクリプトを実行すると、パラメーターが設定されてから、次のように計算を実行する関数が呼び出されます。

param1 = 4;
param2 = {.1, .3, .5};
runTheCalculation[param1, param2]

これがスクリプトの最初の実行であると仮定すると、次のコンテンツがDBに挿入されます。

jobs:   id      param1     param2_id
         1       4.0        1

param2: param2_id   value
         1           0.1
         1           0.3
         1           0.5

ここまでは順調ですね。ここで、1つの異なるパラメーターを使用してスクリプトを再度実行するとします。

param1 = 2;
param2 = {.1, .3, .5};
runTheCalculation[]

単純な実装では、これにより、データベースに次のものが含まれるようになります。

jobs:   id      param1     param2_id
         1       4.0        1
         2       2.0        2

param2: param2_id   value
         1           0.1
         1           0.3
         1           0.5
         2           0.1
         2           0.3
         2           0.5

{.1, .3, .5}しかし、リストがすでにデータベースにあるという事実を検索できるようにしたいので、2回目の実行後、DBには代わりにこれが含まれます。

jobs:   id      param1     param2_id
         1       4.0        1
         2       2.0        1

param2: param2_id   value
         1           0.1
         1           0.3
         1           0.5

{.1, .3, .5}リストがテーブルにすでに存在することを見つけるために、どのような種類のクエリを使用できますparam2か?

必要に応じて追加のテーブルを作成することに反対していません。または、より意味のあるジャンクションテーブルを使用する以外のモデルがある場合は、それでも問題ありません。

4

3 に答える 3

1

リストが短く、リストの数が比較的少ない場合は、 内のリストを順番に並べて、TBL_Lists自分のリストが一致するかどうかを確認できます。これは、保存されているすべてのリストを列挙して、保存されている1 つのリストと比較するため、非常に非効率的です。

別の方法、そして私の意見ではより良い方法は、リストをハッシュし、そのハッシュをTBL_List_Hashes

リストをハッシュするには、一度列挙する必要があります。

ハッシュ アルゴリズムの例としては、並べ替えられたすべての数値の文字列を作成し、均一にパディングしてから、連結された文字列に対して任意のハッシュ メソッドを実行することが考えられます。

特定のリストのハッシュを取得し、DB から一致するハッシュを取得するのは比較的簡単なはずです。衝突を伴う比較的単純なハッシュ アルゴリズムを使用しても、比較を行うために検証する必要があるリストの数を大幅に減らすことができます。

したがって、ハッシュ アルゴリズムに衝突がある場合、誤った一致ごとに列挙 (およびクエリ) の費用が追加されます。

編集: .net .net 3.5 List<T> Equality と GetHashCode
に関連する回答は次のとおりです。

EDIT2:
マッチングで順序にとらわれない場合は
、リストオブジェクトを持つクラスのGetHashCodeをハッシュする前に、リストの順序を標準化するだけです

于 2011-12-16T22:49:00.057 に答える
1

あなたは尋ねます: 与えられたリストがすでにデータベースにあるかどうかを調べるにはどうすればよいですか?

通常の方法はインデックスを使用することであり、インデックスは常に行指向です。そのため、標準的なデータベース設計では、リスト全体 (正規化されたもの) を 1 行にまとめる必要があることが示唆されています。

SQLLite を使用しているため、選択肢はあまりありません。

http://www.sqlite.org/datatype3.html

私はテキストをお勧めします!BLOB にもインデックスを付けることができ、BLOB はいくらかのスペースを節約しますが、おそらく TEXT は問題なく動作し、通常は TEXT の方がデバッグや操作がはるかに便利です。解析/生成できるリストの標準的な文字列形式を発明し、常にデータベースから一貫した方法で INSERT/SELECT するようにしてください (たとえば、一貫した丸め、事前に並べ替え、重複を削除し、末尾と先頭のゼロを常に使用するなど)。一貫性があります)、あなたは大丈夫なはずです。

警告: これは低技術のアプローチであり、おそらく「正しくない方法 (TM)」でさえありますが、うまくいけば....

于 2011-12-17T01:15:57.433 に答える
0

一般に、非常に珍しい一連の要件があり、結果を予測するのに十分な実地経験がない限り、リストは使用しないでください。

ジャンクション テーブルに含まれる多対多のリレーションシップは、適切なインデックスを使用して同様に機能し、はるかに使いやすくなります。また、より柔軟です。

于 2011-12-17T16:03:58.803 に答える