4

生の形式(csvおよびバイナリ)でかなりの量のデータを蓄積しました-正確には数か月間、1日あたり4GBです。

私は文明世界に参加し、データベースを使用してデータにアクセスすることにしましたが、正しいレイアウトは何だろうと思いました。形式は非常に単純です: タイムティック (ビッド、アスク、タイムスタンプなど) ごとに数行 x 最大 50 万/日 x 数百の金融商品 x 数か月のデータ。

コモディティ ハードウェア (2 x 1GB RAID 0 SATA、コア 2 @ 2.7GHz) で動作する MYISAM (このタイプの使用に適したエンジンであると私は理解していました) を備えた MySQL サーバーがあります。

データベースの正しいレイアウトは何ですか? テーブル/インデックスはどのように見えるべきですか? このシナリオでの一般的な推奨事項は何ですか? 途中で私に落とし穴を設定するものは何だと思いますか?

編集:私の一般的な使用法は、特定の日付と楽器の時系列情報を抽出する単純なクエリです。

SELECT (ask + bid) / 2
  WHERE instrument='GOOG'
  AND date = '01-06-2008'
  ORDER BY timeStamp;

編集: timeStamp によってインデックス付けされた 1 つのテーブルにすべてのデータを詰め込もうとしましたが、遅すぎました。したがって、より複雑なスキームが必要になると考えました。

4

6 に答える 6

7

あなたは自分のバックグラウンドが何であるか、プログラミングとデータベース設計についてどれだけ知っているかについてはあまり言いません。読書をする必要があるようです。概念的には、デザインはかなり単純です。あなたの説明は、たった 2 つのエンティティを識別します。

  • 金融商品; と
  • 見積もり。

したがって、属性を識別する必要があります。

金融商品:

  • セキュリティコード;
  • 市場;

見積もり:

  • タイムスタンプ;
  • 金融商品;
  • 入札価格; と
  • 価格を尋ねます。

金融商品への参照は、外部キーと呼ばれるものです。各テーブルには主キー、おそらく自動インクリメント フィールドも必要です。

概念的にはかなり単純です。

CREATE TABLE instrument (
  id BIGINT NOT NULL AUTO_INCREMENT,
  code CHAR(4),
  company_name VARCHAR(100),
  PRIMARY KEY (id)
);

CREATE TABLE quote (
  id BIGINT NOT NULL AUTO_INCREMENT,
  intrument_id BIGINT NOT NULL,
  dt DATETIME NOT NULL,
  bid NUMERIC(8,3),
  ask NUMERIC(8,3),
  PRIMARY KEY (id)
)

CREATE INDEX instrument_idx1 ON instrument (code);

CREATE INDEX quote_idx1 ON quote (instrument_id, dt);

SELECT (bid + ask) / 2
FROM instrument i
JOIN quote q ON i.id = q.instrument_id
WHERE i.code = 'GOOG'
AND q.dt >= '01-06-2008' AND q.dt < '02-06-2008'

データセットが十分に大きい場合は、(ビッド + アスク) / 2 をテーブルに含めて、その場で計算する必要がないようにすることができます。

これが正規化されたビューです。この後、パフォーマンスの最適化を開始する必要がある場合があります。MySQL に何十億もの行を保存することについて、この質問を考えてみてください。パーティショニングは MySQL 5.1+ (かなり新しい) の機能です。

しかし、自問すべきもう 1 つの質問は次のとおりです。このすべてのデータを保存する必要がありますか? 私がこれを尋ねる理由は、私が以前オンライン ブローキングで働いていて、非常に限られたウィンドウのすべての取引のみを保存しており、取引はクオートよりも小さなデータ セットになるためです。

数十億行のデータを格納することは深刻な問題であり、解決するには真剣な支援が必要です。

于 2008-12-29T10:04:54.010 に答える
2

あなたがする必要があるのは、データベースの正規化について読むことです。その記事が多すぎると感じた場合は、第 3 正規形のチュートリアルに目を通してください。

于 2008-12-29T10:10:47.010 に答える
2

ティック レベルでデータを格納する場合、多くの金融データベースは、少なくとも金融商品ごとにデータを分割します。したがって、楽器ごとのテーブルは正常です。さらに進んで日付ごとに分割し、楽器/日付の組み合わせごとに表を作成するものもあります。これにより、複数の日付にわたるクエリが標準である場合、クエリが非常に難しくなる可能性があります。

したがって、2つのオプション:

  1. タイムスタンプにクラスター化されたインデックスを含む、金融商品ごとのティック テーブル
  2. タイムスタンプにクラスター化されたインデックスを含む、金融商品/日付ごとのティック テーブル

これは、アクセス速度とクエリの容易さの間の基本的なトレードオフです。

于 2008-12-29T10:45:31.103 に答える
1

Dani さん、私は Tick by Tick データを何年も扱ってきました。喜んで協力させていただきます。Hotmail で IanTebbutt にメールしてください。(ちなみに、私が確認したところ、StackOverflow でプライベート メールを送信する方法はありません。Jeff は拒否されたようです。)

簡単に言えば、日付と楽器によるパーティション分割がうまく機能することがわかりました。InstrumentX_YYDD のようなパターンを使用して、楽器 X の 1 か月分のデータを一連のテーブルに入れることを選択できます。次に、データにアクセスするときは、少なくともテーブル名ジェネレーターが必要ですが、使用する単一のテーブルを決定したり、場合によっては Union を使用して複数のテーブルを調べたりできる SQL ジェネレーターが必要です。

どのように見ても、この種のデータ ボリュームを処理するのは容易ではありません。これは DataWarehouse の領域に近づいており、その猫の皮を剥ぐ方法は数多くあります。私が言ったように、喜んで協力します - 私はおそらくあなたの問題の半分をすでに解決しています.

于 2009-01-18T02:42:47.770 に答える
1

または、スター スキーマ、ディメンション、およびファクトを検討することもできます。Ralph Kimball が、その方法を説明する素晴らしいものをいくつか持っています。

于 2008-12-29T14:41:44.403 に答える
0

いくつかの一般的な観察:

  • TIMESTAMP列は時間に基づいて自動的に設定されるため、使用しないでくださいINSERT。データをインポートしているので、それはあなたが望むものではありません。
  • MySQLDATETIME列タイプを使用する場合は、MySQL の日付と時刻関数を使用できます。
  • MyISAM は制約をサポートしておらずFOREIGN KEY、黙って無視します。
  • インデックス、インデックス、インデックス。ルックアップに使用する列にそれらがあることを確認してください。ただし、テキストが多い列がある場合は、代わりにFULLTEXT検索を使用することをお勧めします。
  • これをINSERTs とSELECTクエリを使用してライブ データベースに変換する予定がある場合は、トランザクションと行レベル ロックで InnoDB を使用することを検討してください ( SELECT ... FOR UPDATE)
于 2008-12-29T15:19:17.073 に答える