2

さまざまなエンティティを持つDBテーブルを使用しています。これは、あらゆる種類の異なるエンティティを保存するために、任意の数のフィールドを含めることができないことを意味します。代わりに、最も重要なフィールド(日付、参照ID-他のさまざまなテーブルへの外部キーの種類、最も重要なテキストフィールドなど)と、より完全なオブジェクトデータを格納する追加のテキストフィールドだけを保存したいと思います。

最も明白な解決策は、XML文字列を使用してそれらを格納することです。2番目に明白な選択はJSON、通常はより短く、おそらくシリアル化/逆シリアル化もより高速です...そしておそらくより高速です。しかし、それは本当にですか?JsonSerializerは通常何でもシリアル化できるため、私のオブジェクトも厳密にシリアル化可能である必要はありません。匿名のオブジェクトでさえ、ここで使用することもできます。

この問題を解決するための最適な解決策は何でしょうか?

追加情報

私のDBは高度に正規化されており、Entity Frameworkを使用していますが、外部の超高速全文検索機能を使用するために、DBの非正規化を少し犠牲にしています。情報のためだけに、MySqlの上でSphinxSEを使用しています。Sphinxは行IDを返します。これを使用して、インデックスに最適化されたコングロマリットテーブルを高速クエリし、DB全体の複数のテーブルをクエリするよりもはるかに高速に最も重要なデータを取得します。

私のテーブルには次のような列があります。

  • RowID(自動増加)
  • EntityID(実際のエンティティの-ただし、これは別のテーブルを指す必要があるため、直接関連していません)
  • EntityType(必要に応じて実際のエンティティを取得できるようになります)
  • DateAdded(このテーブルに追加されたときにタイムスタンプを記録します)
  • Title
  • Metadata(特定のエンティティタイプに関連するシリアル化されたデータ)

このテーブルは、SPHINXインデクサーでインデックス付けされます。このインデクサーを使用してデータを検索するときは、一連のEntityIDs制限日を指定します。RowIDsインデクサーは、非常に限られたページ数の注文DateAdded(降順)を返す必要があります。RowIDs次に、これらをテーブルに結合して、関連する結果を取得します。したがって、これは実際には全文検索ではなく、フィルタリング検索になります。この方法では取得が非常に高速になり、テーブルから結果を取得する方が、適切にインデックスが作成されていても、比較や比較RowIDsよりもはるかに高速になります。EntityIDsDateAdded

4

4 に答える 4

3

SQL データベースにデータを保存し、長期的な苦痛につながらない唯一の方法は、適切な正規化されたインデックス付きスキーマを実際に作成し、ドメイン オブジェクトに新しいプロパティを追加するときに必要に応じてそのスキーマを拡張することです。

オブジェクトを SQL データベースに「シリアライズ」しようとしないでください。それが本当にやりたいことであれば、代わりにdb4oなどのオブジェクト データベースを使用することをお勧めします。


アップデート:

これは、コメントと質問の更新に基づいて、現在問題空間を理解している方法です。

  • テーブル構造はすでに正規化されています。
  • 特定の検索を最適化するためにフルテキスト エンジン (Sphinx) が使用されています。
  • ここで説明する特定の「シリアル化された」データは、個々の検索結果の要約またはプレビューとして使用され、完全なオブジェクト データを表すものではありません。

これに対する私の選択は、優先順に次のようになります。

  • FTS エンジンの機能を使用します。
    Sphinx を含むほぼすべての FTS エンジンでは、カスタム属性を各「ドキュメント」の一部として保存できます。現在、このテーブルに参加できるように、行 ID のみを保存していると言っています。まったく参加せず、この情報をフルテキスト インデックス自体に保持すると、結果がはるかに速く返されます。ここに入力できる内容にはかなり厳しい制限がありますが、制限を回避できる場合は、それが最善の選択肢です。

  • ドキュメント指向データベース。
    あなたは、Sphinx の「フルテキスト」部分を実際には使用していないと言います。特定のクエリを最適化するために使用しているだけです。では、中間業者を切り捨ててみませんか?シリアル化形式として JSON を提案しました。MongoDB (オプションを 1 つだけ挙げると) はBSON をネイティブにサポートします。共通の列にインデックスを作成することはできますが、mysql とは異なり、実際には BSON 形式を理解し、JSON または XML 文字列よりもはるかに効率的にそのデータをリレーショナル データベースに格納できます。とにかく非正規化する場合は、必要なリポジトリを自由に選択できます。特定の要件に最適化されたものを選択してください。

  • 単一テーブルの継承。
    これは、マッピングの単純化のために正規化をトレードオフする一般的な設計です。あなたの場合、全体の目的は非正規化であるため、それは良い取引です。数百の列がある場合、これは適切なオプションではありませんが、10 または 20 の場合はこれで問題ありません。データを「データ」として保持し、パフォーマンスに大きな影響を与えるべきではありません。

  • XML 列。
    このアプローチの利点は、データが不透明でないことです。データベースのコンテキストでは実際に意味があります。この情報をmysql データベースに保存する必要がある場合(おそらくアドホック クエリが実行されることが予想されます)、mysql が実際に理解できる形式で保存することもできます。一方、アプリケーションに到達するまでこのデータを「逆シリアル化」する必要がないと 100% 確信している場合は、おそらく...

  • カスタム バイナリ シリアル化形式。データを mysql データベースに保存する必要
    あり、インデックスを作成したり、クエリ内からその内容を読み取ったりする必要がないことが確実にわかっている場合は、肥大化したテキスト エンコーディングで貴重な I/O を無駄にしないでください。JSON はすべてのプロパティ名を格納する必要があるため、JSON でさえバイナリに比べて肥大化します。独自のシリアル化を行う場合は、1 バイトまたは 2 バイトを使用して型を決定し、残りのフィールド/プロパティを既知の順序で逆シリアル化できます。データのみで、メタデータはありません。 ここでは .NET を使用することさえせず、高度に最適化された独自のバージョンを作成します。結局のところ、これは高速で高速である必要があります

    BinaryFormatterテーブルに余分なバイトが入るたびに、クエリが遅くなります。内容によっては、一部のデータを GZip 圧縮することもできます。


あなたの要件をまだ完全に理解していない限り、他の選択肢は考えません。

于 2010-04-14T15:25:22.857 に答える
1

しないでください。それは悪い考えです。

本当にやらなければならないのなら、私はXMLを使います。たとえば、SQL Serverでは、フィールドがXMLタイプである限り、XMlに対してクエリを実行できます。

ある意味で、あなたはオブジェクト指向データベースが行っていたことを行っています。ほとんどの場合、HibernateやMicrosoftのEntity FrameworkなどのORMツールを使用すると、OOとリレーショナルの両方の世界を最大限に活用できるため、これらは支持されなくなりました。

于 2010-04-14T15:22:26.200 に答える
0

NoSqlデータベースを見たことがありますか?

http://nosql-database.org/

そうでなければ、あなたのデータモデルは将来あなたを困難に導く可能性があると言わざるを得ません...

于 2010-04-14T15:20:33.520 に答える
0

実際、私は RDBMS で常にテキスト BLOB を使用しています。適切な目的で使用すると、パフォーマンスにプラスの影響を与え、多くのテーブルの存在とメンテナンス、および開発時間を節約できます。行に関する頻繁に変更される非リレーショナル メタデータを格納する必要がある場合に最適です。

KVOオブジェクト(つまり、非エンティティ-永続化された行でのみ意味のあるオブジェクト)にテキストブロブを使用することのみを検討しますが。また、サーバー側の操作、つまりクエリなどを行う必要がある場合も気にしないでください。

興味のある人のために、テキスト BLOB を人間が読めるコンパクトなテキスト形式で格納するのに理想的な、高速で弾力性のあるType Serializerを開発しました。

于 2010-08-18T22:46:38.417 に答える