2009-08-26 2 views
2

基本的なテーブルスキーマは、このような何か(私はところでMySQLを使用しています)になります。リレーショナルデータベースはベクトル計算に適していますか?

integer unsigned vector-id
integer unsigned fk-attribute-id
float attribute-value
primary key (vector-id,fk-attribute-id)

ベクトルが同じベクトル-idを持つテーブル内の複数のレコードとして表現されるの

この表にあるすべてのベクトルのドット積(ユークリッド距離も含む)で別のテーブルを作成する必要があります。だから、私はこのようになり、結果表が必要です。

integer unsigned fk-vector-id-a
integer unsigned fk-vector-id-b
float euclidean-distance

...

integer unsigned fk-vector-id-a
integer unsigned fk-vector-id-b
float dot-product


...と、このようなものを私の結果を生成するための最良のクエリ構造は何ですか?

非常に大きなベクトルの場合、リレーショナルデータベースはこの問題を解決する最良のアプローチですか、またはアプリケーション内でベクターを内部化してそこで計算を行うべきですか? MySQL

+0

は異なるベクトルが異なる寸法を持つことができますか?同じ次元を持つ2つのベクトルが異なる属性セットを持つことができますか?すなわち、3次元属性{長さ、幅、高さ}を有することができ、別のものは{重量、年齢、色} –

+0

を有することができるのは明らかにドット製品を行うために2つのベクトルが同じN空間すなわち、次元は同じでなければならない。 –

+0

はい、ベクトルは異なる次元にすることができますが、属性の重複だけが内積に含まれます。 –

答えて

4
INSERT 
INTO dot_products 
SELECT v1.vector_id, v2.vector_id, SUM(v1.attribute_value * v2.attribute_value) 
FROM attributes v1 
JOIN attributes v2 
ON  v2.attribute_id = v1.attribute_id 
GROUP BY 
     v1.vector_id, v2.vector_id 

、これは速くなります

INSERT 
INTO dot_products 
SELECT v1.vector_id, v2.vector_id, 
     (
     SELECT SUM(va1.attribute_value * va2.attribute_value) 
     FROM attributes va1 
     JOIN attributes va2 
     ON  va2.attribute_id = va1.attribute_id 
     WHERE va1.vector_id = v1.vector_id 
       AND va2.vector_id = v2.vector_id 
     ) 
FROM vector v1 
CROSS JOIN 
     vector v2 
+0

これは動作しますが、クエリのパフォーマンス特性は何ですか? JOINは大規模なベクターテーブルを完成するのに1年かかりますか? –

+0

'@JR Lawhorne':もしあなたが'(atttribute_id、vector_id) 'にインデックスを持っていれば、結果セットをアプリケーションに引っ張って新しい値を構築して戻すよりもおそらく早いでしょう。 – Quassnoi

+0

'WHERE v1.vector_id

関連する問題