5

「id」を複数の列(つまり、いくつかの整数値[u、v、w])の完全なテーブル(複数の行を含む)にマッピングするという単純なパターンに従うデータを格納する必要があります。これらのテーブルの1つのサイズは数KBになります。基本的に私が必要とするのは、いくつかの中間結果の永続キャッシュを保存することです。

これは単純なSQLとして非常に簡単に実装できますが、いくつかの問題があります。つまり、ディスク上のこの構造のサイズを可能な限り圧縮する必要があります。(保存している値の量のため)また、トランザクションではなく、一度書き込んでテーブル全体の内容を読み取るだけでよいため、リレーショナルDBは実際にはあまり適していません。

誰か良い提案があったかしら?どういうわけか、まともなATMを思い付くことができないようです。特にJavaのAPIを使ったものがいいでしょう。

4

7 に答える 7

3

これは....の仕事のようですねnew ObjectOutputStream(new FileOutputStream(STORAGE_DIR + "/" + key + ".dat");!!

真剣に-最も簡単な方法は、保存するデータテーブルごとにファイルを作成し、データをシリアル化し、読み取りたいときにファイル名としてキーを使用して検索することです。

適切なファイル システムでは、書き込みをアトミックにすることができます (一時ファイルに書き込み、ファイルの名前を変更することにより)。読み取り/書き込み速度は、数十 MBit/秒で測定されます。ルックアップは、単純なディレクトリ ツリーを作成することで非常に効率的にすることができますSTORAGE_DIR + "/" + key.substring(0,2) + "/" + key.substring(0,4) + "/" + key。これは、数百万のエントリでも効率的であり、ファイル システムがインデックス付きディレクトリを使用している場合はさらに効率的です。最後に、さらに高速な検索のために、この上にメモリ バックアップされた LRU キャッシュを実装するのは簡単です。

圧縮に関して - Jakarta の commons-compress を使用して、データを保存する前に gzip または bzip2 圧縮に影響を与えることができます。ただし、これは最適化の問題であり、アプリケーションと使用可能なディスク容量によっては、CPU サイクルを他の場所に投資した方がよい場合があります。

私が作成した実装例を次に示します: http://geek.co.il/articles/geek-storage.zip。設定された最大サイズでキャッシュからオブジェクトを格納および取得するためのメソッドを提供する単純なインターフェイス (クリーンとはほど遠い - 概念の単なるデモンストレーションです) を使用します。キャッシュミスは処理のためにユーザー実装に転送され、キャッシュはストレージ要件を超えていないことを定期的にチェックし、古いデータを削除します。

また、MySQL を使用した実装を完成させ、ディスク ベースの実装と MySQL ベースの実装を比較するためのベンチマークも含めました。私のホーム マシン (古い Athlon 64) では、ディスク ベンチマークのスコアが、付属のベンチマークでの MySQL 実装の 2 倍よりも優れています (9.01 秒対 18.17 秒)。DB の実装を微調整して、パフォーマンスをわずかに向上させることができるかもしれませんが、問題を十分に示していると思います。

これを自由に使用してください。

于 2009-03-12T15:28:42.143 に答える
2

私はEHCacheを使用します。これは Hibernate やその他の Java EE ライブラリで使用されており、非常にシンプルで効率的です。

テーブルを追加するには:

List<List<Integer>> myTable = new(...)
cache.put(new Element("myId", myTable));

読むには:

List<List<Integer>> myTable = (List<List<Integer>>) cache.get("myId").getObjectValue();
于 2009-03-12T15:29:31.080 に答える
1

Berkeley DBを見たことがありますか?それは法案に合うかもしれないように聞こえます。


編集:

値を保存する前に、値自体をgzipで圧縮できることを追加するのを忘れました。次に、それらを取得するときに解凍します。

于 2009-03-12T15:14:54.183 に答える
1

Apache Derbyは、(別個のサーバーではなく) 埋め込みが必要な場合に適している可能性があります。

その他のオプションのリストは、Lightweight Data Bases in Java にあります。

于 2009-03-12T15:47:20.193 に答える
0

JOAFIP http://joafip.sourceforge.net/を使用できます 。これにより、すべてのデータ モデルをファイルに入れることができ、メモリにすべてを再ロードすることなく、それにアクセスして更新することができます。

于 2009-04-03T22:59:28.810 に答える
0

Key=>Value Databasesが検索対象のようです。

おそらく、 SuperCSVが最適なフレームワークです!

リレーショナル データベースを使用したくない場合は、JAXBを使用してオブジェクトを XML ファイルとして保存できます。

XStreamのような他のライブラリを使用する方法もあります

XML を好む場合は、JAXB または XStream を使用してください。それ以外の場合は、SuperCSV などの CSV ライブラリを確認する必要があります。シリアライズされた Java ファイルを扱うことができる人は、Guss が言ったように、デフォルトの永続化メカニズムを使用できます。ダイレクト Java 永続化が最速の方法かもしれません。

于 2009-03-12T16:09:50.483 に答える
0

数 KB ある場合、「ディスク上のこの構造のサイズを可能な限り圧縮する」必要がある理由がわかりません。心配するのに時間をかけすぎる価値はありません。

ただし、質問に答えるために、書き込み時にファイルを圧縮できます。ObjectOutputStream と同様に、XMLExcoder を使用してマップをシリアル化できます。これは、ObjectOutputStream を使用するよりもコンパクトになり、ファイルを解凍すると、データを読み取ったり編集したりできるようになります。

XMLEncoder xe = new XMLEncoder(
    new GZIPOutputStream(
        new FileOutputStream(filename+".xml.gz")));
xe.writeObject(map);
xe.close();
于 2009-04-04T11:00:48.683 に答える