0

C++ 11 でデータを複数のファイルに高速シリアル化するには、何を使用できますか (データの冗長性を避けるために、データを複数のテーブルに分割し、ID 番号で結合すると仮定します)?

私は使用することを考えています:

  1. fstream.read(), でアクセスする単純なバイナリ ファイルfstream.write()
  2. を使用してmmap
  3. 関数google protobuf(すべてを繰り返すのではなく、ランダムな要素にアクセスできる場合)。

uint8すべてのテーブルは、次のデータ型の列で構成され ます: uint16、、、、、。uint32uint64string

4

3 に答える 3

1

ここでは、高速ランダム アクセスが課題になります。これを実現する最も簡単な方法は、各行のサイズを一定に保つことです。protobuf控えめな最大サイズを想定しない限り、sを使用してこれを行う簡単な方法はありません。最初の 2 つのオプションのいずれかを使用すると、比較的簡単にこれを行うことができます (文字列のサイズに妥当な制限があると仮定します)。

ただし、任意にさらに複雑にすることもできます。s を使用protobufすると、単純なシリアル化よりも使用するスペースが少なくなる可能性が高いため、インデックスを構築するためのメモリが残ります。比較的小さなインデックス (たとえば、テーブルの行番号から 100 行ごとのファイル オフセットへのマッピング) でさえ、高速なランダム アクセスが可能になり、使用するスペースが大幅に少なくなります。もちろん、これは単純なすべての行を同じサイズにするアプローチよりもかなり複雑です。

于 2012-04-30T16:29:29.510 に答える
1

MIT ライセンスのシリアライゼーション ライブラリCap'n Protoは、必要な機能を提供する場合があります。Google Protobuf Kenton Vardaの主な作者によって書かれました。

彼からの引用: Cap'n Proto はポインターを使用して、完全なランダム アクセスをサポートします。これは、mmap() のような巨大なファイルを実行して、実際にはすべてを処理せずに内部オブジェクトを 1 つ取り出したり、サブオブジェクトに書き込まれた順序とは異なる順序でアクセスしたりできることを意味します。

あなたが言及しているデータ型(uint8、uint16、uint32、uint64、string)はすべてCap'n Proto Schema Languageでサポートされています

于 2015-09-29T20:46:25.450 に答える
1

数値ストレージと文字列ストレージを分離します。

スパース テーブル、数値データ

数値型の列には列ストアを使用します。列ストアは NULL 値を格納せず、テーブル行を再現できる結合ロジックを提供します。

シングル ルックアップ ランダム アクセスではありませんが、特に列ストアのインデックスがメモリ内にある場合は、スペースのトレードオフが優先される可能性があります。

高密度テーブル、数値データ

読み取り用のファイルを MMAP します。一定の幅でデータを行ごとに保存します。必要なキャッシュと先読みの利点を得るには、ファイルを開くパラメーターを微調整する必要がある場合があります。

fstream.write() を使用して書き込みを行う方がおそらく高速です。

文字列データ

あなたの提案に基づいて、あなたの設計ではテーブルを一度に書き込んでから、その時点から読み取り専用のランダム アクセスを実行できるように思えます。もしそうなら、Google の SSTableを見てください。これは、可変長データに効率的なランダム アクセスを提供するストレージ レイヤーです。

于 2012-05-01T01:22:53.480 に答える