2

ウェブ上でこれを行っている例を見つけることができないので、おそらくその理由があるのではないかと考えています (または、適切な検索用語を使用していない可能性があります)。私が気付いていない、これに対する用語がすでにあるかもしれませんか?

定期的に繰り返される文字列のためにデータベースのストレージ スペースを節約するために、unique_stringという名前の MySQL テーブルを作成することを考えています。次の 2 つの列しかありません。

  1. "id " : INT : PRIMARY_KEY インデックス
  2. "string" : varchar(255) : UNIQUE インデックス

データベース内の任意の場所にある他のテーブルは、VARCHAR 列の代わりに INT 列を使用できます。たとえば、browserという varchar フィールドは、代わりにbrowser_unique_string_idという INT フィールドになります。

パフォーマンスが重要な場合には、これを使用しません。この場合、私はそれを使用して、すべてのページ リクエストの詳細 (Web 統計のログ) とイントラネットでのユーザー アクションの「監査トライアル」を追跡していますが、他のことも可能です。

また、SELECT クエリが複雑になることも承知しているので、それについて心配する必要はありません。「実際の」文字列データを返すクエリを生成するコードを書く可能性が高いでしょう。

考え?ここで明らかなことを見落としているような気がします。

ありがとう!

4

3 に答える 3

1

私は、この構造を同様のアプリケーション (Web ログの URI を追跡する) に使用しました。この場合、データベースは Oracle でした。

パフォーマンスの問題は最小限ではありません。データベースが大きくなるにつれて、URI は数千万に上ります。そのため、INSERT 中に正しい文字列を識別するだけでも困難です。Hadoop でほとんどの更新ロジックを構築することでこれを処理したため、データベース テーブルは本質的に Hadoop テーブルの単なるコピーでした。

通常のデータベースでは、質問で提案しているように、インデックスを作成することでこれを回避します。また、インデックス ソリューションは、使用可能なメモリまでうまく機能します。実際、これはインデックスのかなり退化したケースです。実際にはインデックスのみが必要であり、基になるテーブルは必要ないためです。mysql や SQL Server がこれを認識するかどうかはわかりませんが、柱状データベース (Vertica など) は認識するはずです。

SQL Server には別のオプションがあります。文字列を VARCHAR(max) として宣言すると、残りのデータとは別のデータ ページに保存されません。全テーブル スキャン中に、列がクエリで参照されていない場合は、追加のページをメモリにロードする必要はありません。

于 2012-05-22T14:46:17.350 に答える
0

(バッチ ジョブではなく) リアルタイムでデータを記録することを計画している場合は、データベースにレコードを書き込む時間をできるだけ短くする必要があります。同期的にログを記録している場合、明らかにレコード作成時間は、http 要求が完了するまでにかかる時間に直接影響します。これが非同期の場合、レコードの作成時間が遅くなり、ボトルネックが発生します。ただし、これがバッチ ジョブの場合、次のバッチが実行される前に、バッチ処理されたすべてのレコードを自信を持って作成できる限り、パフォーマンスは問題になりません。

データベース構造を本当にフラットにしたいレコードを作成するのにかかる時間を短縮するために、疑似での現在のクエリは次のようになります

SELECT @id = id from PagesTable
WHERE PageName = @RequestedPageName

IF @id = 0
THEN 
  INSERT @RequestedPageName into PagesTable
  @id = SELECT @@IDENTITY 'or whatever method you db supports for              
                          'fetching the id for a newly created record
END IF

INSERT @id, @BrowserName INTO BrowersLogTable 

フラットな構造の場合は、INSERT が 1 つだけ必要です。

データの整合性を懸念している場合は、通常、このデータを定期的に別のテーブル セット (または別のデータベース) に書き込むときにクエリを実行して正規化し、これをクエリに使用します。

于 2012-05-22T14:23:18.233 に答える
0

これは、データのカーディナリティが、リンク先のトランザクション テーブルと比較して比較的小さいデータベースで非常に一般的な設計パターンです。クエリはそれほど複雑ではなく、ルックアップ テーブルへの単純な結合だけです。ルックアップ テーブルには文字列だけでなく、一般的に繰り返されるその他の情報を含めることができます。モデルを正規化して重複データを削除しているだけです。

例:

リクエスト表:

Date    
Time   
IP Address    
Browser_ID  

ブラウザテーブル:

Browser_ID
Browser_Name
Browser_Version
Browser_Properties
于 2012-05-22T14:09:59.490 に答える