QA@IT

MySQLで大きなサイズのデータを効率よく追加書き込みする方法

3697 PV

今現在下記のようなSQLを用いて、大規模データ(※1レコードに数十MB~数百など)を書き込んでいきたいと思っています。

UPDATE test_table SET data=CONCAT(data,"test test test test") WHERE id=1; (ポイントのみ抜粋したSQL)

テーブル : test_table
data : LONGTEXT

しかしながら、ある程度蓄積すると、途中でColumn 'data' cannot be nullとなり、それ以上蓄積することができません。

○ご質問
1.回避する方法はありますか?

2.また、CONCAT以外に文字列を追加する方法はありますか?

3.キーに対してある程度大きなデータを蓄積(追記)していきたいと思っていますが(※)、何かいい方法はご存知でしょうか?
(MySQL以外でも問題ありません。)

※イメージ
ウェブサーバー(複数台) ⇔ ストレージ用途のサーバー(→この部分を検討中)

宜しくお願いします。

回答

その後、私の方でもなんとか希望の方法で格納する方法を模索しましたが、検討ではMySQLを利用することを断念しました。メイン部分がMySQLのため、MySQLでなんとかできる方法を検討していましたが、やはり適していない選択だと思いました。

ほんの一部分のニーズでもあるため、結局初期時はファイル格納にしようと思います。用途が増えた時にHBaseなどのその他のミドルウェアを検討したいと思っているところです。

編集 履歴 (0)

原則的にRDBMS一般において、レコード内のデータ量を増加する場合は極端に時間がかかります。

RDBはファイルの中にレコード単位でデータを順に記録する仕組みです。
ですから、書き込み済みのレコードの後は別のデータで埋まっているのが普通です。
もとのレコードの場所に収まらなくなれば、分割するか、消して書き直すしかありません。
前者は全体のパフォーマンスを落とすので、RDBMSは後者を行うことが多いようです。

3.キーに対してある程度大きなデータを蓄積(追記)していきたいと思っていますが(※)、何かいい方法はご存知でしょうか?
列方向にデータを増やすのではなく、行方向に増やすようにするのが一般的です。

編集 履歴 (0)
  • 返信遅くなりました。有難うございます。 -

MySQLにはmax_allowed_packetというパラメータがありますが、これはいくつに設定されていますか?
デフォルトだと1MBだと思います。

MySQLのマニュアルに以下のような記述があります。
http://dev.mysql.com/doc/refman/5.1/ja/string-functions.html

文字列値の関数は、結果の長さが max_allowed_packet システム環境変数より長くなると、NULL を返します。

おそらくこの仕様が原因になっていると思いますので、max_allowed_packet の設定を変えてください。
必要な設定は環境で変わりますが、とりあえず16MBくらいに変えておくとよいです。
設定値の反映には、MySQLの再起動が必要です。

編集 履歴 (0)
  • あと、この値の上限は1GBです。
    http://dev.mysql.com/doc/refman/5.7/en/server-system-variables.html#sysvar_max_allowed_packet
    -
  • 回答有難うございます。マニュアルの転載有難うございます。

    蓄積は上限内では可能となりましたが、パフォーマンスが著しく悪い状況です。(データが大きくなっていくので当たり前かもしれません)

    処理として、既に蓄積済みのデータに追記するようなSQLは、やはり存在しないものでしょうか?
    (詳しく調べきれていませんがCONCATは、既存のデータ+追加データを上書きする処理かと思います。)
    -
  • CONCATは文字列連結関数ですよ。
    http://dev.mysql.com/doc/refman/5.1/ja/string-functions.html
    括弧内の文字列を順番に連結してくれます。上書きが実行されているのは、UPDATE文を実行しているからです。
    -
ウォッチ

この質問への回答やコメントをメールでお知らせします。