4

MySQL テーブルで TEXT フィールドの値を一意にしたい。

ちょっとした調査の結果、パフォーマンスの問題のために、誰もが TEXT フィールドで UNIQUE INDEX を使用することを思いとどまらせていることがわかりました。私が今使いたいのは:

1) TEXT 値のハッシュ (md5(text_value)) を含む別のフィールドを作成します。

2) このハッシュ フィールドを UNIQUE インデックスにする

3) クエリで INSERT IGNORE を使用する

このソリューションは完全で、安全で、最適ですか? (SOで見つけました)

この目標を達成するためのより良い方法はありますか?

4

2 に答える 2

3

コメントでこれを解決する方法を尋ねられたので、回答として書きます。

このような状況は、アプリケーションの設計に誤りがあることを示唆しています。それが何を意味するか考えてみてください。

事前に長さを指定できないテキストがあり、非常に長くなる可能性があり (最大 64k)、一意性を維持したい場合。このような量のデータが個別のキーに分割され、複合インデックスを構成して一意性を生成することを想像してください。これがあなたがやろうとしていることです。整数の場合、これは複合インデックスに結合された 16000 個の整数のインデックスになります。

さらに、CHARACTER 型フィールド (CHAR、VARCHAR、TEXT) がエンコードによって解釈されることを考慮してください。これにより、問題がさらに複雑になります。

何らかの方法でデータを分割することを強くお勧めします。これにより、DBMS が可変長の文字ブロックを組み込む必要がなくなるだけでなく、データの一部に対して複合キーを生成する可能性が生じる可能性があります。もしかしたら、データ用のより優れたストレージ ソリューションを見つけることさえできるかもしれません。

質問がある場合は、テーブルおよび/またはデータベース構造を投稿し、TEXT フィールドに含まれる論理データと、一意である必要がある理由を説明することをお勧めします。

于 2013-03-08T14:53:01.753 に答える
2

ほぼ完成です。ハッシュとの衝突が発生する可能性 (Birthday Paradox) があるため、UNIQUE インデックスだけでは十分ではありません。

完全に安全にするには、比較チェックと一緒にハッシュを使用することをお勧めします。

SELECT COUNT(*) FROM table
WHERE md5hash = MD5(text)
AND textvalue = text

これは、INSERT または UPDATE TRIGGER にラップすることも、簡単にチェックできるように STORED PROCEDUR にラップすることもできます。

this Stack Overflow questionハッシュ衝突の例を見てください。

于 2013-03-08T13:26:13.567 に答える