7

MySQL を使用してスキーマレス データを保存しています ( FriendFeed が MySQL を使用してスキーマレス データを保存する方法に着想を得たソリューションについては、「スキーマレス データにリレーショナル データベースを使用する」を参照してください)。

1 つの大きなテーブルに、アプリケーションのすべてのエンティティが保持されます。

CREATE TABLE entities (
  added_id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY
, id BINARY(16) NOT NULL
, body MEDIUMBLOB
, UNIQUE KEY (id)
) ENGINE=InnoDB ;

いくつかの詳細:

  • 格納されたエンティティの唯一の必須プロパティはid、16 バイトの UUID です。エンティティの残りの部分は、データベースに対して不透明です。に新しいプロパティを格納するだけで、「スキーマ」を変更できますbody

  • このadded_id列が存在するのは、InnoDB が物理的にデータ行を主キーの順序で格納するためです。AUTO_INCREMENT 主キーにより、古いエンティティの後に新しいエンティティがディスクに順次書き込まれることが保証され、読み取り/書き込みの局所性に役立ちます (新しいエンティティは古いエンティティよりも頻繁に読み取られます)。

  • 私たちのデータベースは、スキーマレス データを に保存しますbody<-これがこの質問のトピックです。

  • 非同期マテリアライズド ビュー (インデックスはオフラインで構築される単なるテーブルです) を構築するためにデータに「到達」するなど、他にも興味深い詳細がたくさんありbodyますが、現在の議論には関係ありません...

の構造化データ (キーと値のペア) をどのようにシリアル化する必要がありbodyますか?

フィールド名が行ごとに繰り返されるため、JSON または BSON は単純です。これにより、柔軟性が向上しますが、スペース効率が大幅に低下します (シリアル化されたデータのフィールド名の行ごとのオーバーヘッド)。物事をメモリに保持しようとしていますが、ここではメモリとネットワークのフットプリントの両方を最小限に抑えることが重要です。同じスペースに収まるレコードが多いほど、クエリは高速になります。私たちは比較的長くてわかりやすいフィールド名を好みますが、データベースを高速化するためにフィールド名を短くするのは間違っています!

最終的に、JSON/BSON は、データベースと対話するアプリケーション ドライバーで、より複雑になり、小さなキーをよりわかりやすいキーにマップしない限り、この目的には使用できません。それは私たちに考えさせました...

私たちのデータベースはスキーマレスですが、実際には: 1) エンティティの種類はそれほど多くありません。2) 同じ種類のエンティティのバージョンが頻繁に変更されることはありません。3) 変更された場合、通常は追加するだけです。別のフィールド。JSON/BSON には、バージョン管理のネイティブ サポートはありません。

Protocol Buffers と Thrift は、バージョン管理とデータ定義の変更に関しては、はるかに洗練されています。Thrift と Protocol Buffers はどちらも、データをデータベースにシリアル化するための優れた候補であり、Thrift はエンコード形式が拡張できるように設計されています。

Protocol Buffers は、スキーマレス データベースでデータをシリアル化するための優れた選択肢のように見えます。

CouchDB と MongoDB (最も人気のある 2 つのスキーマレス データベース?) はそれぞれ JSON と BSON を使用しますが、スキーマレス データを格納するためのシリアル化形式として、Protocol Buffers のようなより高度なものを使用することについては何も見つかりません。特定の言語バージョンのオブジェクトを格納する製品 (つまり、Java の外部化可能オブジェクトをデータグリッドに格納する、または Ruby で MySQL を使用して NoSQL を実行する) がありますが、これらは面倒です (他のプラットフォームから、または MySQL 自体からアクセスしてみてください。バージョン管理は忘れてください)。

相互運用性の高いプロトコル バッファをデータベースに保存したり、他の高度なシリアル化形式をスキーマレス データベースに保存したりする人はいますか? これは、JSON/BSON/XML の単純な行ごとのシリアル化や、特定の言語のオブジェクトのシリアル化以外に、他のオプションがあるかどうかという問題です。それは実現可能ですか?何か不足していますか?意識流のナラティブでごめんなさい!

4

4 に答える 4

3

ご存知のように、MongoDBとCouchDBは、データの保存方法について強い意見を持っています。ストレージにとらわれないアプローチを探している場合は、@ Josephが提案するようなことをして、CassandraまたはHBaseを調べてください。これらの2つのデータストアでさえ、データの保存方法(どちらもGoogleのBigtableに基づいています)と列ファミリーへのデータの保存方法について意見があります。

Riakは、アプリケーションからデータストアにデータをシリアル化する1つの方法としてプロトコルバッファを使用します。それがあなたのニーズに合っているかどうかを確認する価値があるかもしれません。主に単一キーのルックアップを実行することを計画しているように見えるので、Riakはソリューションの強力な候補になる可能性があります。

于 2010-11-30T13:01:49.217 に答える
1

データを保存するために、Cassandra や HBase などを検討することをお勧めします。不透明なデータ BLOB の問題は、MySQL スキーマでこれに基づいてクエリを実行できないことです。何かを探している場合は、すべてのブロブを読み込んでチェックする必要があります。それがルックアップの方法にとって本当に重要ではない場合 (つまり、常にキーになる場合)、プロトコル バッファーを使用してデータをシリアル化し、おそらく zlib または LZO 圧縮で圧縮することをお勧めします。

プロトコル バッファを使用すると、データの変化に応じて追加のフィールドを受け入れることができる単純なデータ構造を作成できます。フィールド名は数値として保存され、構造を操作するコードが .proto ファイルから自動的に生成されます。パフォーマンスは良好で、データ サイズは非常に小さく保たれています。必要に応じて、MySQL の compress() を使用するか、ここにまとめたリアルタイム圧縮ライブラリ (Java だけでなく) のいずれかを使用して、データを圧縮できます。

Javaで高速圧縮?

お役に立てれば。

于 2010-11-25T02:36:04.650 に答える
1

PostgreSQL に JSON 型が追加されました: http://www.postgresql.org/docs/9.3/static/datatype-json.html

これらの値に「到達」するクエリを作成できます。

Protobuf を JSON に変換するのは非常に簡単です。

于 2014-03-06T10:22:40.307 に答える
0

数か月前に同様のトピックについて提案した回答を紹介します。MySQL と、XML や JSON 形式よりも高速であることが証明されたカスタム テキスト形式を使用します。

NoSQL データ ストアを使用して、どのようなスケーラビリティの問題に遭遇しましたか?

私たちのためにうまくいっています。ただし、Protocol Buffers は試しませんでした。

于 2010-11-30T13:07:04.460 に答える