0

64 ビット整数のタイムスタンプと Sting ユーザー名を 1 つの文字列に結合し、最終的にデータベース列に格納します。それらを適切な型の別々の列に保存できない理由は別として、私の質問は、それらを組み合わせて基礎となるデータベースのパフォーマンスを向上させる方法です。それは sqlite、PostgreSQL、または MySQL になりますが、まだわかりません。

タイムスタンプは通常常に進行し、ツリーは頻繁にバランスを取る必要があるため、(timestamp-username) のように連結するのは良くありません。username-timestamp ははるかに優れているはずですが、それでも各ユーザー レコードは新しいエントリごとに増加します。タイムスタンプもビットの逆順で入れようと思っていました。

他にできることはありますか?賢いxorか何か?合理的に最適なスキーマは何でしょうか? データは、範囲などではなく、正確に生成された文字列を要求することによってアクセスされます。

唯一の要件は、生成された文字列とソース データの間で、両方の方法で比較的高速に変換することです。

更新: 皆さん、データベース (sqlite、mysql、postgresql のいずれか) の主キーとして格納するのに適した文字列の種類について情報を求めています。おそらく答えは、問題ではないか、DB エンジンに依存しているということです。使用しているスキーマやキャッシュ ソリューションに特に問題はありません。改善の余地があるかどうか、そしてその方法を尋ねているだけです。話題に沿った回答をいただければ幸いです。

UPDATE2:素晴らしい答えはまだ決定的ではありません: インクリメントされた列は、列のbツリーインデックスを不均衡にしますか? https://stackoverflow.com/a/2362693/520567

4

2 に答える 2

1

あなたの質問には矛盾があります。それらを分割して別々の列に保存することはできないと指定していますが、両方の部分を別々にインデックス付けすることについて話している-それらを分割せずにそれを行うことはできません。

2 つの選択肢があることがわかります。

  1. それらを別々の列に保存する
  2. 出力をハッシュしてインデックスのメモリ フットプリントを下げる

理想的には、それらを常に同じ順序で一緒に検索する場合は、それらを 2 つの列に格納し、複合インデックスを作成する必要があります。その場合、最初に詳細な情報を提供せずに正確なアドバイスを提供することは困難ですが、一般に、ユーザーごとにクエリを実行する場合はユーザー名、タイムスタンプが論理的に意味があり、タイムスタンプでクエリを実行する場合は逆になります。どちらか一方を検索する必要がある場合は、各列にインデックスを作成することもできます。

生成された文字列をハッシュする

INSERT INTO table (crc_hash_column, value_column_name)
values (CRC32(@generated_value), @generated_value)

サイズを 32 ビット整数 (1 行あたりわずか 4 バイトのインデックス) に縮小し、必要な同等の VARCHAR または CHAR インデックス スペースよりもはるかに小さくなります。

このアプローチを取る場合は、誕生日のパラドックスが発生するため衝突を回避する手段を講じる必要があり、データセットが大きくなるにつれて発生する可能性が高くなります。衝突があっても、インデックスのサイズを考えると、追加のフィルタリングにより、代替手段よりも優れたパフォーマンスが得られます。

SELECT * FROM table
WHERE crc_hash_column = CRC32(@search_value) 
AND value_column_name = @searchvalue

ハッシュを使用すると、さらにいくつかの CPU サイクルが発生しますが、CRC32 ハッシュは非常に高速であるため、検索するたびに再ハッシュする必要がありますが、この余分な作業は、大量のデータのインデックス作成に比べてわずかなメリットがあります。

通常、私は最初のオプションを好みますが、ユースケースを知らずに推奨することはほとんど不可能です.

両方のオプションをプロファイリングして、要件に適合するかどうかを確認する必要があります。

于 2013-03-27T21:39:53.843 に答える
0

それらを別々の列に保持することはできないと言います(1:1の関係で新しいテーブルを設定することもできません/トリガーを使用してデータをマテリアライズドビューにミラーリングすることもできません/既存のテーブルを修正されたテーブルのビューに置き換えることもできません構造 ????!!!!) は、どのソリューションも醜いハックになることを意味します。

はい、データがどの程度変更され、どのように構造化されているかは、更新の効率に影響します。ただし、インデックスの目的は検索を高速化することです。データがどのようにアクセスされるか、どのように変更される可能性があるかについての情報は提供されていません。

タイムスタンプもビットの逆順で入れようと思っていました

なんで?これにより、インデックスの断片化が減少するよりも高速化される可能性が高くなります。

MariaDB は仮想列と仮想列のインデックスをサポートしているため、正規化のルールを窓の外に投げ出すなどのばかげたことを行うことができますが、スキーマの些細な問題を修正できない場合は、DBMS を置き換えることはおそらくありません。どちらか非常に実用的なソリューションです。

率直に言って、すでに適切なソリューションと同じくらいのコストがかかり、将来コストが発生する可能性が高い問題に対する悪いソリューションを開発するのに時間とお金を費やす価値がある場合、悪いソリューションを選択することは時間とお金の両方の無駄です。

于 2013-03-27T22:24:49.680 に答える