1
1

More than 1 year has passed since last update.

MySQLのint型での誤解

Posted at

はじめに

int(n)という、int型にするときのカッコ内の数字の意味を誤解していました。
そして調べていくうちに、そもそも非推奨となっていることを知りました。
同じように誤解している方の目に止まればいいなと思います。

実行環境:mysql : 8.0.33

int(n)は、n桁の整数という意味ではない  

たとえば int(3) だと、-999〜999 が有効な範囲になると思っていました。
しかし実際には10000を入れてもちゃんと10000を取り出せます。

mysql> CREATE TABLE int_check1 (id int(3));
mysql> INSERT INTO int_check1 VALUES (10000);
mysql> SELECT * FROM int_check1;
+-------+
| id    |
+-------+
| 10000 |
+-------+

int(n)は、nに何を指定しようとも有効範囲は変わらない

まず n = 3 の場合を、int型に格納できる最大数と最小数の境界で確認します。

mysql> INSERT INTO int_check2 VALUES (2147483647);
Query OK, 1 row affected (0.01 sec)
mysql> INSERT INTO int_check2 VALUES (2147483648);
ERROR 1264 (22003): Out of range value for column 'id' at row 1

mysql> INSERT INTO int_check2 VALUES (-2147483648);
Query OK, 1 row affected (0.02 sec)
mysql> INSERT INTO int_check2 VALUES (-2147483649);
ERROR 1264 (22003): Out of range value for column 'id' at row 1

mysql> SELECT * FROM int_check2;
+-------------+
| id          |
+-------------+
|       10000 |
|  2147483647 |
| -2147483648 |
+-------------+

MySQLでのintの有効範囲は -2147483648 〜 2147483647 です。

このようにnが小さい場合でも、int型としての限界まで格納できます。

nが有効桁数オーバーでも問題ない

次に、新しくデータ型を int(20) としたカラムを持つテーブルを作成して確認してみます。

mysql> CREATE TABLE int_check3 (id int(20));

mysql> INSERT INTO int_check3 VALUES (2147483647);
Query OK, 1 row affected (0.02 sec)

mysql> INSERT INTO int_check3 VALUES (2147483648);
ERROR 1264 (22003): Out of range value for column 'id' at row 1

mysql> SELECT * FROM int_check3;
+------------+
| id         |
+------------+
| 2147483647 |
+------------+

MySQLでのintの最大有効桁数は10桁です。
それをオーバーする20を指定しても問題なく、挙動は int(3) と変わりません。

int(n)のnは、表示幅を指定している

新しくデータ型を int(3)、int(15) としたカラムを持つテーブルを作成して確認してみます。
MySQLでの表示の際に、自動でゼロフィルされるようにオプションとしてZEROFILL指定をします。

mysql> CREATE TABLE int_check4 (
    ->    id1 int(3) ZEROFILL,
    ->    id2 int(15) ZEROFILL
    -> );

mysql> INSERT INTO int_check4 
    -> VALUES (12, 12), 
    ->        (123, 123), 
    ->        (1234, 1234),
    ->        (2147483647, 2147483647);

mysql> SELECT * FROM int_check4;
+------------+-----------------+
| id1        | id2             |
+------------+-----------------+
|        012 | 000000000000012 |
|        123 | 000000000000123 |
|       1234 | 000000000001234 |
| 2147483647 | 000002147483647 |
+------------+-----------------+

このようにZEROFILLを使うと、表示幅を指定した影響が確認できます。

留意点

この件を調べる過程で公式ドキュメント1 2 を読み学んだ中で、上記に関連した内容を記載します。

int(n)という表示幅指定と、ZEROFILL属性は非推奨になっており、今後サポートされなくなる。

今回の誤解原因である機能は、近い将来に無くなるようです。
表示幅指定の機能削除はあくまで整数データ型のみですが、そもそも小数データ型の場合の (n) は、ちゃんと(表示幅ではない)桁数に関係しているようです。
MySQLで小数のデータ型を扱ったことがなかったので、そういった違いに気付きませんでした。
さらに同じ小数データ型でも、floatやdoubleなどの種類によっても意味が変わるようです。

一応、int(n)の表示幅の指定はアプリケーション側でも利用されているようなので、ZEROFILL属性を持たせなくても指定に意味があったみたいです。

しかし完全にint(n)の機能は削除されるので、今後は使わないのが正解なのでしょう。

表示幅は、LPAD()関数を使えば、あとからでも指定できます!

  1. https://dev.mysql.com/doc/refman/8.0/ja/numeric-type-syntax.html

  2. https://dev.mysql.com/doc/refman/8.0/ja/numeric-type-attributes.html

1
1
0

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
1
1