4

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

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

各画像には独自の情報 (キャプチャ パラメータ) があり、相互に関連する画像のグループの一部 (たとえば、同じ 30 分間に撮影されたもの) になり、全体としてより大きなグループの一部 (同じ人物が撮影されたもの) になります。 )。現在、一意の識別子を持つ辞書に人を保存しています。次に、各人物にはさまざまな写真グループのリストがあり、各写真グループには写真のリストがあります。これらのクラスはすべてシリアライズ可能で、辞書をシリアライズおよびデシリアライズしているだけです。かなり簡単なもの。辞書が天文学的なサイズにならないように、画像は個別に保存されます。

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

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

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

ありがとう!

4

6 に答える 6

2

ちょっとした警告、SQLLite、プロトコル バッファ、mmap など...すべて非常に優れていますが、各実装のプロトタイプを作成してテストし、同じパフォーマンスの問題や異なるボトルネックに遭遇しないようにする必要があります。

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

于 2008-09-27T00:28:08.983 に答える
2

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

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

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

于 2008-09-26T21:39:41.917 に答える
1

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

Mマップを参照

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

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

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

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

于 2008-09-26T21:45:08.470 に答える
1

現時点では頭がおかしいので、データベースに賛成か反対かをアドバイスできるかどうかはわかりませんが、バージョンにとらわれないシリアル化を探しているなら、少なくともProtocol Buffersにチェックインしないのはばかです。

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

于 2008-09-26T21:49:45.573 に答える
0

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

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

データベーステーブルでは、新しい属性を取得した場合、Alter Table Picture AddAttributeDataTypeと言うことができます。次に、属性に値が必要であるというルールを作成しない限り、古いバージョンをロードして保存できます。同時に、新しいバージョンは新しい属性を使用できます。

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

おそらく、テーブルは
Picture(PictureID、GroupID?、ファイルパス、キャプチャパラメータ1、キャプチャパラメータ2など)である必要があります。

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

Person(PersonID、Name / Etc。などの任意のPerson属性)
Group(GroupID、Group Name、PersonID?)
PersonGroup?(PersonID、GroupID)
PictureGroup?(GroupID、PictureID)

于 2008-09-26T22:40:06.107 に答える