20
10

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

MySQLで長い文字列=TEXT型と安易に考えてはいけない

Last updated at Posted at 2019-02-15

wysiwygエディタで入力したhtmlをデータベースに保存するというのはよくあるケースではないかと思います。
今回は、エディタを保存するフィールドを何も考えずTEXT型にしてしまうと、不具合になるかもよ!というお話です。

ある日のテストで、登録処理を通ったのにエディタに何も出てこない不具合を発見。

  • ログにエラーは吐かれていない。
  • エディタを外しても現象は再現する。
  • 別所で同じエディタを使っている所は通るし、中身も出る。

phpから取ったsqlを投げてみると

error 1406 - Data too long for column

指定のフィールドを見てみると途中でエディタに入力した内容が途切れていました。
よくよく見ると、中身が出たデータも途中で切れています。

根本的な原因
TEXT型の最大値の量を超えたため。
MySQL 5.6 リファレンスマニュアルには

最大長が 65,535 (216 − 1) 文字の TEXT カラム。値にマルチバイト文字が含まれる場合、有効な最大長は少なくなります。各 TEXT 値は、値のバイト数を示す 2 バイト長のプリフィクスを使用して格納されます。

とあるので、日本語だと4万文字もあればキャパオーバーしそうです。

なぜ真っ白に?
入っているデータの出だしは以下の通り。

[{"craft":"<p>boss<\/p>\r\n","~

json_encodeされていますね。
途中で途切れた結果、閉じ括弧がなくjson_decodeが出来なかったのでしょう。

なぜ正常に通ってしまったのか
SQLを抽出してMySQLで投げると通らないパターンがちょいちょいあります。大体NULL関係と文字長さで引っかかるんですが。。。
フレームワークによるものなのか何なのか、詳しい方是非ご教授お願いいたします。

対策
きちんと使用目的に合った型を宣言する事。
今回はどれだけの長さになるか想定できないので対象のフィールドをLONGTEXT型とし解決しました。
それだけでなくquery長(SQL文の文字数)にも制限があるので注意。
 詳しくはmax_allowed_packetなどで検索検索ゥ!
最大文字数に合わせて各input項目にバリデーションがあると尚良いかなと思います!

決してTEXT型に限ったお話でもないので、皆様もサイレント文字数カットによる不具合にお気をつけ下さい。:point_left::smiley_cat:

20
10
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
20
10

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?