はじめに
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()
関数を使えば、あとからでも指定できます!