質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.58%

株価時系列データのMySQLへの保存 テーブルの作成方法について

解決済

回答 3

投稿

  • 評価
  • クリップ 1
  • VIEW 1,652

GARYU

score 8

前提・実現したいこと

全銘柄の株価の時系列データをMySQLに取り込み保存したいと思ってます。
データ自体は某サイトよりcsvファイルを取り込み、MySQLへ読み込もうと思います。
そのcsvファイルは1ファイル1日分となっており、列方向に各銘柄の証券コード・銘柄名・始値・高値・安値・終値・出来高が、行方向に銘柄が入っています。
毎日そのcsvファイルを取り込み、保存しているデータに新しい日付のデータを追加していく形でデータベースを日々更新したいと思います。

保存したデータの使い方としては、主にテクニカル面でのスクリーニングに使います。
例えば「ここ二週間で株価130%以上になっている銘柄の一覧」や「移動平均の乖離が10%を超えている銘柄一覧」や「RSIが25以下の銘柄一覧」を表示するといった感じです。
また新しい手法のバックテストを行う為に、決まった数のデータではなく毎日追加した分だけデータ数が増えるデータベースにしたいと思ってます。

「株価時系列データ」という名前の全銘柄の時系列データが入ったデータベースを作ろうと思っていますが、ここでテーブルの作り方はどちらが良いのか教えて頂きたいと思います。
1.一銘柄=1テーブル
2.全銘柄=1テーブル
色々ネットを探してみましたが、「銘柄はそんなに変わるものではないので1銘柄=1テーブルのほうが良いのでは?」という意見もあれば「テーブルの数が大量になると検索に時間が掛かる」との意見もあり、どうなんだろう?となっています。
またそれぞれの形にも疑問があります。

《一銘柄=1テーブルを選んだ場合》
Q1.テーブル名を証券コード+企業名にしたいと思ってますが、4000銘柄以上あるので4000テーブル以上を[CREATE TABLE]文で一テーブルずつ作っていくしか方法がないのか?
Q2.取り込もうとしているcsvファイルは全銘柄が1ファイルとなってますが、そのファイルを読み込んだ時に各テーブル(該当する銘柄のテーブル)にちゃんとデータが振り分けられるのか?
Q3.上に書いたようにスクリーニングをする際は何らかの計算が発生するが、「〇〇の検索条件を満たした銘柄」として一覧で出力出来るのか?
《全銘柄=1テーブルを選んだ場合》
Q4.日付を含むと一銘柄に対して8項目のデータがあり、×4000の項目を一つずつ作っていく方法しかないのか?

いくつもの質問が入ってしまいすみません。
データベース設計の中での一連の疑問ですのでご容赦ください。

また全く違う形でもスクリーニングに使えれば問題ありませんので上記以外でも「こんな形にしてみたら?」というものがあればぜひともご指導お願いします。

発生している問題・エラーメッセージ

エラーまで辿りつけていません。
しかしすぐにつまずくと思いますので、また質問させていただきます。
その際はお手柔らかにご指導お願いします。

該当のソースコード

上記理由と同じ。

試したこと

上記理由と同じ。

補足情報(FW/ツールのバージョンなど)

Windows10・mySQL8.0

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 3

checkベストアンサー

+2

基本的に「銘柄ごとの検索」しか行わない、ということであれば、「テーブルを分けたほうが良いのか?」という考えになるのも理解はできます(複数銘柄をまとめて検索することがよくある、ということであれば、そもそもテーブルを分けるのはおススメしません)。

ただ、「一銘柄=1テーブルを選んだ場合」のところでご自身で仰っているとおり、様々なデメリットがあります。
テーブルを分割する目的が「銘柄検索時に対象となるデータサイズを小さくすること」であれば、テーブルは1つのままにして、テーブルパーティションを使うと良いと思います。

https://qiita.com/taroshin/items/608076c9f8e09497c4b1

パーティショニング単位は、今後の使用用途によって、最適な単位が異なります。

・基本的には証券コードによる検索しか行わない場合(複数証券コードをまたいだ検索、もしくは、証券コードを指定しない検索はごく稀)

証券コードのRANGEで分割するのがおススメです。
適当な番号毎(例:1000毎)に分割しても良いですし、もし「この業種の○○」といった検索をよく行うのであれば、証券コードは業種別にある程度ルールが決まっているので、各業種の証券コード範囲毎に分割しても良いと思います(テーブルパーティションをまたいだ検索は遅くなるので)。

https://kabukiso.com/apply/knowledge/code.html

・基本的には日付指定検索しか行わない場合(複数日付をまたいだ検索、もしくは、日付を指定しない検索はごく稀)

日付のRANGEで分割するのがおススメです(データ量的に、月単位、もしくは年単位辺りが無難かと思います)。
ただし、日付単位の場合、定期的にパーティションを追加する必要があります。
(あらかじめ、50年分くらい未来分を作っておく、という方法も無くはないのですが、不要なパーティションは無駄&速度低下の元になるので、必要に応じて作成していくほうが無難です)

《全銘柄=1テーブルを選んだ場合》
Q4.日付を含むと一銘柄に対して8項目のデータがあり、×4000の項目を一つずつ作っていく方法しかないのか?

とありますが、項目を×4000作る必要は無いのではありませんか?

日付+CSVファイルに格納されている項目ということで

日付・証券コード・銘柄名・始値・高値・安値・終値・出来高

を1レコードとして、これを4000レコード登録すれば良いだけです。
(テーブルのプライマリキーは日付・証券コード or 証券コード・日付。作成するテーブルパーティションによって、キーの順番を変える必要があります)

その場合、証券コードが xxxx の全データが欲しい時は

SELECT * FROM 株価の時系列テーブル WHERE 証券コード = xxxx;

日付が xxxx/xx/xx の全銘柄データが欲しい時は

SELECT * FROM 株価の時系列テーブル WHERE 日付 = 'xxxx/xx/xx';

で検索すればOKです。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

+2

「株価時系列データ」という名前の全銘柄の時系列データが入ったデータベースを作ろうと思っていますが、ここでテーブルの作り方はどちらが良いのか教えて頂きたいと思います。
1.一銘柄=1テーブル
2.全銘柄=1テーブル

設計に於いては、1なんて普通選択しません。

《一銘柄=1テーブルを選んだ場合》
Q1.テーブル名を証券コード+企業名にしたいと思ってますが、4000銘柄以上あるので4000テーブル以上を[CREATE TABLE]文で一テーブルずつ作っていくしか方法がないのか?

そういう選択をしているんだからそうなりますね。
動的にテーブルを作るというのは、そもそも正規化されていないという事になります。

Q2.取り込もうとしているcsvファイルは全銘柄が1ファイルとなってますが、そのファイルを読み込んだ時に各テーブル(該当する銘柄のテーブル)にちゃんとデータが振り分けられるのか?

そういったプログラムを組まないとできません。さらに非常に面倒です。

Q3.上に書いたようにスクリーニングをする際は何らかの計算が発生するが、「〇〇の検索条件を満たした銘柄」として一覧で出力出来るのか?

出来なくは無いですけど、銘柄追加を考慮した動的な問い合わせになりますね。

《全銘柄=1テーブルを選んだ場合》
Q4.日付を含むと一銘柄に対して8項目のデータがあり、×4000の項目を一つずつ作っていく方法しかないのか?

殆どのDBMSはCSVをインポートするためのコマンドが準備されています。
13.2.6 LOAD DATA INFILE 構文

そもそも、「一銘柄=1テーブル」という発想があるという事なので、もう少しご自身で正規化等の理解を深められた方が、良いと思います。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

+1

仮に1万銘柄管理するとしても日に1万行、年間でもたった365万行増えるだけです。
ほとんど数値の列なのでデータ量も知れてます。
1テーブルで十分です。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.58%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る