2009-10-28 13 views
10

私は簡単なコンテンツ管理システムを書いています。 私の最大のテーブルの主キーとして外部的に計算されるSHA1ハッシュ値を格納する必要があります。Postgres SQLの主キーとしてSHA1署名を格納する

シーケンスをプライマリキーとして使用し、ルックアップのためにSHA1の16進文字列にインデックスを付けることができます... しかし、私は単純に20バイトを使用するより洗練されたソリューションを探していますSHA1は、データベーステーブルに挿入/削除/更新しようとしている行のキーとして値を計算しました。 SHA1キーを保存して後で主キーとして使用できる効率的なストレージタイプはありますか?

これを達成するためにキーとして20バイト値を使用することをサポートするには、明らかにpostgresが必要です。

誰でもアイデアがありますか?

+4

Btwの場合、すべてのハッシュキーが衝突する可能性があります(SHA1も同様です)。 –

+0

私はSHA1の適切な実装でハッシュの衝突について心配しないでしょう:) http://stackoverflow.com/questions/297960/hash-collision-what-are-the-chancesを参照してください。 – wojo

答えて

1

これがインデックスのbtreesにできることに慎重にしてください。 SHA1はシーケンシャルではないので、btreeのすべてのジャンプのために書き込みが非常に遅くなります。

シーケンスがうまくいかない場合は、通常、ある種のシーケンシャルGUID/UUID(たとえば、SQL ServerのNEWSEQUENTIALID()を参照)をお勧めします。

これを知った後にSHA1をプライマリキーにしたい場合は、SHA1が通常表示される標準の16進形式に変換できます(入力が簡単です)。

+7

'Bツリーに書き込むとにかくシーケンシャルになります、それは周りにジャンプするとリンクするページを探しています。しかし、値を均等に分散させると、ツリーのバランスが取れ、検索がより高速になり、遅くなることはありません。 – Quassnoi

+1

私はいくつかのデータベースサーバーがクラスタードインデックスに従ってページを注文する方法を指していたと思いますが、それはSQL Serverです.pgsqlに該当するかどうかはわかりません。うーん!しかし、あなたは正しいです。ツリーは非常によく(ほぼ完全に)均衡します。 – wojo

+0

'@ wojo':' SQLサーバ 'は、クラスタ化されたテーブルであっても、物理的な順序ではなく 'Bツリー'の順序を保持します。行は必ずしも論理的にのみ物理的に順序付けられているわけではありません。 http://msdn.microsoft.com/en-us/library/ms177443(SQL.90).aspx – Quassnoi

2

16進数または16進数に変換してvarchar列を使用するか、byteaタイプの列に格納してください。私は両方のフォーマットでランダムな値の束を使ってテーブルを作って、それらがどのように実行するかを見てみようと思います。

このタイプの情報は、the PostgreSQL docs on byteaを参照してください。

5

特にバイナリパラメータをdb(libpqなど)に使用する場合は、byteaを使用してください。単純なテキストクエリを使ってたくさんの操作をしたい場合は、hextに変換してtextまたはvarcharカラムに格納します。

もちろん、PostgreSQLは20バイトのキーでは問題ありません。もちろん、パフォーマンスのオーバーヘッドはシーケンスよりも大きくなります。

関連する問題