3

データベースに、2 つのものの類似性を表すテーブルがあります。何かのようなもの:

+------------+------+
| Field      | Type |
+------------+------+
| id_a       | int  |
| id_b       | int  |
| similarity | ???  |
+------------+------+

similarityid_aとの間の類似度をid_bパーセントで保持し、100% 類似 (同一のもの) から0%を含まないまでの範囲で指定できます。0% 似ている (つまり、完全に異なる) ものへのリンクは保存しません。つまり、 range を保存する必要があります[100, 0)。小数点以下の桁数はさほど重要ではありませんが、1 桁か 2 桁がよいでしょう。

私が通常提案している解決策は、のようなものを使用することですdecimal(4,2)。私のユースケースの問題は、それが保存されること(100,0]です。

どちらも を使用していますdecimal(4,2)が、どちらもハックのように見えます。

オプション1

保管し、取り出すときにバックsimilarity - 0.01を追加します。0.01何かのようなもの:

INSERT INTO similarities (id_a, id_b, similarity) VALUES (1, 2, ? - 0.01);

その後:

SELECT id_a, id_b, similarity + 0.01 FROM similarities;

オプション 2

0% ~ 99.99% のパーセント差を格納し、取得時に類似度に変換します。

SELECT id_a, id_b, 100 - difference AS similarity FROM similarities;

MERGEどちらの場合も、クエリに加算と減算を残すのではなく、おそらく を使用してビューを作成します。

これらよりも優れたオプションはありますか? ない場合、どれを選びますか?なぜですか?

ノート:

[1,0)範囲を適切に表している限り、 のような他の表現を使用してもかまいません。

明確にするために編集します。

挿入はめったに行われず、ユーザーではなく私だけが行い、大きなバッチで行われます。挿入するデータは常に [100,0) にあることを知っているので、強制の問題ではなく、最も効率的/自然な表現が何であるかという問題です。

4

2 に答える 2

2

SQL 標準に準拠する dbms では、列を decimal(5, 2) 型として宣言し (または同等の小数を使用)、CHECK 制約を使用して範囲を制限します。

create table data (
  id integer primary key,
  pct decimal(5, 2) not null check (pct > 0 and pct <= 100)
);

しかし、MySQL は SQL 標準に準拠していません。CHECK 制約は適用されません。したがって、2 つの選択肢があると思います。

  1. 範囲をチェックするトリガーを作成し、選択した範囲外の挿入と更新をロールバックします。
  2. 有効な値のテーブルへの外部キー参照を使用します。あなたの場合、そのテーブルには 10,000 行しかありませんよね?

さらなる計算でパーセンテージを使用する必要がある場合は、直接使用できるように、.0001 から 1.0000 の範囲の値を使用することをお勧めします。ただし、それはアプリケーションの問題ではないようです。

于 2013-02-08T14:03:28.040 に答える
0

類似性をパーセンテージとして割り当てる代わりに、sè ごとに、範囲内の類似性スコアを与えます[1,10000](または必要(0,10000]に応じて)。これにより、パーセンテージ ポイントあたり 100 ポイントが得られます (必要に応じて効率的に小数点以下 2 桁)。

保管所:int(32)

意見:SELECT id_a, id_b, similarity/100 FROM similarities;

于 2013-02-08T14:24:35.013 に答える