【mysql】Decimal型のカラムを定義するときの罠


サービスを作っています

どうも!mokabuu.comです!

最近、身近な人たちとのレクリエーションのためにサービスを作っています。

完全に趣味の領域です。

今は、ギルドを組んで毎日歩いた歩数を登録することで、ギルド全体の累計歩数で開始地点からどこまで移動できたのか計測できる健康促進のサービスを作っています。ただ歩数を登録できるだけでは楽しくないので、現在地点にコメントを残せるようにしたりして、コラボレーションを創出できる仕組みを作ったりしています。

僕のGoogleのAPI課金が青天井に伸びていかないように、招待制のサービスにしておりますが、興味がある方がいらっしゃいましたらお声がけください。毎月の余裕をみつつアカウントを発行します。


mysqlのdecimal型

さて、現在、僕が作っているサービスは「歩数を距離に換算して地図の上を旅するサービス」です。なので移動後の現在地は「緯度・経度」で表現しています。

そのため現在地にコメントを残す際は「緯度・経度」の情報をコメントとあわせてDBに格納する仕組みを採用しました。

このとき、僕は重大な勘違いをしており躓いたのです。何回、地図の座標を保存しても「0.99999999(9の数は厳密には忘れた)」とかにしかならなかったんですよね。

これ何故かと言うと、僕の仕様の誤認によりカラムが正しく作られてなかったからでした。

mysqlでは、decimal型のカラムを作成する際に桁数を(M,D)の形で指定します。正しくは以下の通りです。

  • M…扱う少数の最大桁数
  • D…小数点以下の桁数

なので「XXX.XXXXXX」としたければ

  • M…9桁
  • D…6桁

と登録すべきでした。一方で僕は

  • M…6桁(整数部分が3桁と勘違い、しかし3で登録を試みたところDより小さい数は設定できないとのことだったので6をセット)
  • D…6桁

と登録していたので、全部で6桁登録できるうちの6桁が少数という仕様でテーブルが作られておりました。

ちゃんとドキュメントを読めっていう話ですね。

たとえば、DECIMAL(18,9) カラムは小数点の両側に 9 桁あるため、整数部と小数部のそれぞれに 4 バイトが必要です。DECIMAL(20,6) カラムは整数部に 14 桁、小数部に 6 桁あります。整数部の桁は、そのうちの 9 桁に 4 バイト、残りの 5 桁に 3 バイトが必要です。小数部の 6 桁には 3 バイトが必要です。

出典:https://dev.mysql.com/doc/refman/5.6/ja/precision-math-decimal-characteristics.html

僕と同じ罠にハマる方、意外と多いのではないかと思ったので記事にしてみました。

え?誰もそんなミスしないって?

それはそれで平和な世界線なので良しとしましょう!←


最後まで読んでいただきありがとうございます。もしこの記事を気に入って頂けたようであればシェアをお願い致します。非常に励みになります。


コメントを残す