データを保存する最良の(無料の)方法は?ファイルシステムの更新はどうですか?

StackOverflow https://stackoverflow.com/questions/142114

  •  02-07-2019
  •  | 
  •  

質問

この問題を解決する方法についてのアイデアはありますが、自分の問題に対してもっと簡単で拡張可能なものがあるかどうか知りたかったのです。

私が取り組んでいるプログラムには、2つの基本的なデータ形式があります。画像と、それらの画像に関連する情報です。画像に関連付けられた情報は、以前は非常に単純なJETデータベース(4つのテーブル)に保存されていましたが、保存されたフィールドでは時間がかかり、不完全でした。データストレージの新しい実装に移行しています。関連するデータ構造の単純さを考えると、データベースは過剰であると考えていました。

各画像は、それ自身の情報を持ち(キャプチャパラメータ)、相互に関連する画像のグループの一部になり(たとえば、同じ30分間に取得されます)、その後、より大きなグループの一部になります(取得されます)同じ人)。今、私は一意の識別子を持つ人々を辞書に保存しています。その後、各人は異なる画像グループのリストを持ち、各画像グループには画像リストがあります。これらのクラスはすべてシリアライズ可能であり、辞書をシリアライズおよびデシリアライズしています。かなり簡単なもの。画像は別々に保存されるため、辞書のサイズが天文学的になることはありません。

問題は、新しい情報フィールドを追加する必要がある場合はどうなりますか?将来の改訂の可能性を考慮して、これらのデータ構造をセットアップする簡単な方法はありますか?以前は、Cでこれを処理する方法は、将来の拡張性のために空のバイト(少なくともk)がたくさんあるシリアル化可能な構造体を作成し、構造体のバイトの1つがバージョンを示すことでした。次に、プログラムが構造体を読み取ると、大量のswitchステートメントに基づいて使用する逆シリアル化を認識します(余分なデータは無視されるフィールドに移動するだけなので、古いバージョンは新しいデータを読み取ることができます)。

このようなスキームはC#に存在しますか?たとえば、StringオブジェクトとIntオブジェクトのグループであるクラスがあり、別のStringオブジェクトを構造体に追加した場合、ディスクからオブジェクトを逆シリアル化してから文字列を追加するにはどうすればよいですか?データクラスの複数のバージョンと、逆シリアル化ストリームを受け取り、基本クラスに格納されているバージョン情報に基づいて逆シリアル化を処理するファクトリーを所有することに自分を辞任する必要がありますか?または、このような情報を保存するのに理想的な辞書のようなクラスは、ディスク上のすべてのフィールドを自動的にデシリアライズし、新しいフィールドが追加された場合、例外をキャッチし、それらの値を空の文字列とIntに置き換えることができますか?

ディクショナリアプローチを使用する場合、ファイルの読み取り/書き込みとパラメーターの取得時間に関連する速度の低下はありますか?クラスにフィールドがあれば、フィールドの検索はすぐに行われますが、辞書では、そのクラスに関連する小さなオーバーヘッドがいくつかあると思います。

ありがとう!

役に立ちましたか?

解決

現時点では私の脳は揚げられているので、データベースに賛成か反対かをアドバイスできるかどうかはわかりませんが、バージョンに依存しないシリアル化を探しているなら、少なくともチェックインしないでくださいプロトコルバッファ

C#/。NETについて知っている実装の簡単なリストを次に示します。

他のヒント

Sqlite が必要です。これは、ほとんどの言語にバインドされた、高速で埋め込み可能な単一ファイルのデータベースです。

拡張性に関しては、モデルをデフォルトの属性で保存してから、将来の変更に備えて属性拡張用の別のテーブルを作成できます。

1、2年後、コードがまだ使用されている場合は、1)他の開発者がコードを維持するためにカスタマイズされたコード構造を学ぶ必要がないこと、2)エクスポート、表示、標準のデータベースツール(sqliteファイルとさまざまなクエリツール用のODBCドライバーがあります)でデータを変更し、3)最小限のコード変更でデータベースにスケールアップできます。

ほんの一言の警告、SQLLite、Protocol Buffers、mmapなど...すべて非常に優れていますが、各実装のプロトタイプを作成してテストし、同じパフォーマンスの問題や異なるボトルネックに遭遇しないことを確認する必要があります

シンプルさは、SQL(Express)にアップサイズするだけで(perfのゲインに驚くかもしれません)、現在のデータベース設計に欠けているものをすべて修正します。次に、perfがまだ問題である場合は、これらの他のテクノロジーの調査を開始します。

このような状況に対処できるデータベーススキーマがありますが、その名前を思い出せません。基本的に2つのテーブルがあります。 1つのテーブルには変数名が格納され、もう1つのテーブルには変数値が格納されます。変数をグループ化する場合は、変数名テーブルと1対多の関係を持つ3番目のテーブルを追加します。このセットアップには、データベーススキーマを変更し続けることなく、さまざまな変数を追加し続けることができるという利点があります。頻繁に気が変わる部門(マーケティングなど)に対処するときに、ベーコンをかなり節約しました。

唯一の欠点は、変数値テーブルが実際の値を文字列列として格納する必要があることです(実際にはvarcharまたはnvarchar)。次に、値を元の表現に変換する手間を処理する必要があります。私は現在、このようなものを維持しています。現在、変数テーブルには約8億行があります。 1秒未満で値の特定のバリエーションを取得できるため、それでもかなり高速です。

私はC#プログラマーではありませんが、mmap()呼び出しが好きで、C#でそのようなことをしているプロジェクトがあるのを見ました。

Mmap

を参照してください。
  

構造化されたファイルは、特定のアプリケーション向けに調整された場合は非常にパフォーマンスが高くなりますが、管理が難しく、ほとんど再利用できないコードリソースです。より良い解決策は、仮想メモリのような実装です。

     
      
  • 最大4ギガバイトの情報を管理できます。
  •   
  • スペースは実際のデータサイズに最適化できます。
  •   
  • すべてのデータを単一の配列として表示し、読み取り/書き込み操作でアクセスできます。
  •   
  • 保存するために構造化する必要はなく、使用して保存するだけです。
  •   
  • キャッシュできます。   再利用性が高い。
  •   

次の理由から、sqlliteを使用してください。
1.毎回ディスクからデータベース全体を読み書きする必要はありません
2.最初に十分なプレースホルダーを残していなくても、追加するのがずっと簡単です
3.必要なものに基づいて簡単に検索できます
4.アプリケーションの設計以外の方法でデータを変更するのが簡単

辞書アプローチの問題
1.スマート辞書を作成しない限り、毎回データベース全体を読み書きする必要があります(データ構造を慎重に設計しない限り、後方互換性を維持するのは非常に困難です)
----- a)プレースホルダーを十分に残していない場合は、さようなら
2.キャプチャ属性の1つを検索するために、すべての写真を線形検索する必要があるかのように見えます
3. 1つの写真を複数のグループに入れることはできますか?写真を複数の人の下に置くことはできますか? 2人は同じグループに所属できますか?辞書を使用すると、これらのものは毛むくじゃらになります。...

データベーステーブルでは、新しい属性を取得した場合、テーブルの画像を変更して属性のデータ型を追加するだけで済みます。その後、属性に値を設定する必要があるというルールを作成しない限り、古いバージョンをロードして保存できます。同時に、新しいバージョンでは新しい属性を使用できます。

また、データベースに画像を保存する必要はありません。写真へのパスをデータベースに保存するだけで済みます。次に、アプリで画像が必要な場合は、ディスクファイルから読み込むだけです。これにより、データベースのサイズが小さくなります。また、ディスクファイルを取得するための余分なシーク時間は、イメージをロードする時間と比較してほとんど意味がありません。

おそらくあなたのテーブルは
ピクチャ(PictureID、GroupID ?、ファイルパス、キャプチャパラメータ1、キャプチャパラメータ2など)

より柔軟性が必要な場合は、テーブルを作成できます CaptureParameter(PictureID、ParameterName、ParameterValue)... 1つのテーブルに配置するよりもはるかに効率が悪いため、これに反対することをお勧めします(キャプチャパラメータを取得/検索するクエリは言うまでもなく複雑です)。

Person(PersonID、Name / Etcなどの個人属性)
Group(GroupID、Group Name、PersonID?)
PersonGroup?(PersonID、GroupID)
PictureGroup?(GroupID、PictureID)

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top