0

私の質問には2つのサブ質問があります:

  1. キー/値のタプルのセットとして表されるデータを毎秒受信する場合を考えてみましょう。各値は基本的に 64 ビットのカウンターです。データベースに保存する必要があります。値の数は数千です。それらの数千のうち、実際のデータを持っているのは 1% だけで、その他は null (まばらに入力されたセット) です。数千列のテーブルを作成することは理にかなっていますか? または、単に「id、タイムスタンプ、キー、値」として保存しますか?

  2. 質問 1 の答えが「数千の列」の場合、mysql/postgres ファミリのどのデータを使用する必要がありますか?

この場合の読み取りパターンはほとんどがチャートであるため、select はタイムスタンプに基づく一連のデータになります。したがって、すべてのデータまたは日付/時刻範囲内のデータの均一な 1/秒の書き込みと不定期の読み取りです。

おまけの質問ですが、そのようなデータを NoSQL データベースに格納するために使用できるパターンは何ですか? たとえば、MongoDB では、セット全体のわずか 1% のドキュメントを含む統計のコレクションを使用できます。その場合、読み取り/マップ/削減でどのように機能しますか? データの読み取りは mysql/postgres と比べてどうですか?

編集:私のユースケースはNewRelicサービスと非常に似ていますが、小さなデータセットをたくさん持つ代わりに、はるかに大きなデータセット(さらに大きなセットからまばらに取り込まれています)を持っていますが、頻度は低いです(そしてユーザーは少ないです)

4

2 に答える 2

1

PostgreSQL は null 列をビットマップとして保存しますが、各行ごとに大きなオーバーヘッドがあります。2 つのストレージ スキームのストレージ効率を計算してみましょう。

Average row length for wide table with thousands of columns:
23 bytes row header + 1000*1bit + average 2 bytes of alignment + 4 bytes id
   + 8 bytes timestamp + 10*8 bytes values = 242 bytes

Average number of bytes for storing each value separately:
10 values * (23 bytes row header + 1 byte alignment + 4 bytes id
   + 8 bytes timestamp + 4 bytes key + 8 bytes value) = 480 bytes

したがって、1000 列は、キーで分割するよりも約 2 倍効率的です。キーを別々に保存する方が効率的となるクロスオーバー ポイントは、約 0.45%です。

ただし、このアプローチはあまり拡張できません。PostgreSQL の列の最大数は 1600 に制限されています。さらに拡張するには、値を垂直方向に多くのテーブルに分割できます。結果セットも 1600 を超えることはできないため、これにはクエリに関する問題もあります。

もう 1 つのオプションは、キーと値のペアを配列にエンコードすることです。この場合のテーブルの構造は (id serial, ts timestamptz, keys int2[], values int8[]) になります。同じ 1000 個の属性、1% のフィル ファクターのストレージ オーバーヘッドは次のようになります。

23 bytes row header + 1 byte alignment + 4 bytes id + 8 bytes timestamp
   + 20 bytes array header + 10*2 byte values + 20 bytes array header
   + 10*8 byte values = 176 bytes per entry

ただし、この場合、特異値のクエリには、わずかに多くのインフラストラクチャが必要です。

さらに優れたストレージ効率または柔軟性が必要な場合は、カスタム データ型を追加できます。

センサー データの多数の列パターンが、多くの PostgreSQL インストールで正常に使用されていることを知っています。データベースの選択に関しては、少し偏見があるかもしれませんが、PostgreSQL をお勧めします。配列、述語インデックス、カスタム データ型などのはるかに優れたツールを使用して、データ ストレージを再配置して効率を高めることができるからです。覚えておくべき最も重要なことは、最初からパーティショニングを使用することです。

于 2012-10-17T21:54:00.257 に答える
0

何千もの同じデータ型の列を持つテーブルを設計する必要がある唯一のケースは、データベースにこれらの列の外部キー定数を持つ必要がある他のテーブルがある場合です。それ以外は、何千もの列を持つことは、せいぜい管理不可能です。

jdbm2のような永続的なマップ ストレージ エンジンを使用することもできます。あなたのような同様のユースケース向けに設計されています。

于 2012-10-17T21:48:33.267 に答える