16
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【MySQL】整数型の表示幅、、、消えてる!?

Posted at

恥ずかしながら「整数型の表示幅消えてるやん!」ということに今更気づいたので、簡単に調べてまとめておきました。

表示幅とは

INT(11)のような表記で見かける「(11)」の部分、これが「表示幅」と呼ばれるものです。これと、例えばVARCHAR(255)のような文字列型の定義とは異なり、実際のデータが格納される桁数を指定しているわけではありません。

では、INT(4)と指定したら、すべての値が4桁で表示されるのかというとそうではなく、表示幅が反映されるのは、ZEROFILL(ゼロ埋め)の設定がされている場合だけです。
ZEROFILLが有効な場合は指定された桁数未満の数字は0で埋められますが、ZEROFILLの指定がない場合はほとんど意味がありません。
この紛らわしい見た目から、表示幅がデータ長の制約と勘違いしたことがある人も多いはずです。

この表示幅は、MySQL8.0.17以降では非推奨となり、8.0.19以降では一部の例外を除いて指定が無視されるようになりました。この変更は、INTだけでなく、BIGINTSMALLINTなど他の整数型にも共通しています。

実際の挙動

MySQL8.0.16以前

まず、8.0.16以前のバージョンでの表示幅の挙動を確認してみます。

mysql> CREATE TABLE `sample` (
    ->     `default_int_column` int(11) NOT NULL  AUTO_INCREMENT,
    ->     `zerofill_int_column` int(4) zerofill NOT NULL,
    ->     `not_zerofill_int_column` int(4) NOT NULL,
    ->     PRIMARY KEY (`default_int_column`)
    -> );
Query OK, 0 rows affected (0.11 sec)

mysql> DESC sample;
+-------------------------+--------------------------+------+-----+---------+----------------+
| Field                   | Type                     | Null | Key | Default | Extra          |
+-------------------------+--------------------------+------+-----+---------+----------------+
| default_int_column      | int(11)                  | NO   | PRI | NULL    | auto_increment |
| zerofill_int_column     | int(4) unsigned zerofill | NO   |     | NULL    |                |
| not_zerofill_int_column | int(4)                   | NO   |     | NULL    |                |
+-------------------------+--------------------------+------+-----+---------+----------------+
3 rows in set (0.01 sec)

mysql> INSERT INTO `sample` VALUES (12, 12, 12);
Query OK, 1 row affected (0.04 sec)

mysql> INSERT INTO `sample` VALUES (1234567, 1234567, 1234567);
Query OK, 1 row affected (0.08 sec)

mysql> select * FROM `sample`;
+--------------------+---------------------+-------------------------+
| default_int_column | zerofill_int_column | not_zerofill_int_column |
+--------------------+---------------------+-------------------------+
|                 12 |                0012 |                      12 |
|            1234567 |             1234567 |                 1234567 |
+--------------------+---------------------+-------------------------+
2 rows in set (0.01 sec)

このように、ZEROFILLが有効な場合のみ、指定された表示桁数に達するまで0埋めされることがわかります。一方で、INT(4)という表示幅の指定があっても、5桁以上の数字をそのまま保存でき、表示幅によって桁数が強制的に制限されるわけではありません。

MySQL8.0.17

次に表示幅の指定が非推奨となった8.0.17の挙動を見ていきます。

mysql> CREATE TABLE `sample` (
    ->     `default_int_column` int(11) NOT NULL  AUTO_INCREMENT,
    ->     `zerofill_int_column` int(4) zerofill NOT NULL,
    ->     `not_zerofill_int_column` int(4) NOT NULL,
    ->     PRIMARY KEY (`default_int_column`)
    -> );
Query OK, 0 rows affected, 4 warnings (0.02 sec)

mysql> SHOW WARNINGS;
+---------+------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Level   | Code | Message                                                                                                                                                                   |
+---------+------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Warning | 1681 | Integer display width is deprecated and will be removed in a future release.                                                                                              |
| Warning | 1681 | The ZEROFILL attribute is deprecated and will be removed in a future release. Use the LPAD function to zero-pad numbers, or store the formatted numbers in a CHAR column. |
| Warning | 1681 | Integer display width is deprecated and will be removed in a future release.                                                                                              |
| Warning | 1681 | Integer display width is deprecated and will be removed in a future release.                                                                                              |
+---------+------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
4 rows in set (0.00 sec)

mysql> DESC sample;
+-------------------------+--------------------------+------+-----+---------+----------------+
| Field                   | Type                     | Null | Key | Default | Extra          |
+-------------------------+--------------------------+------+-----+---------+----------------+
| default_int_column      | int(11)                  | NO   | PRI | NULL    | auto_increment |
| zerofill_int_column     | int(4) unsigned zerofill | NO   |     | NULL    |                |
| not_zerofill_int_column | int(4)                   | NO   |     | NULL    |                |
+-------------------------+--------------------------+------+-----+---------+----------------+
3 rows in set (0.00 sec)

表示幅とZEROFILLが非推奨であるという警告が出ていますが、表示幅の指定自体はまだ有効です。

MySQL8.0.19以降

最後に、MySQL 8.0.19以降での挙動を確認します。

mysql> CREATE TABLE `sample` (
    ->     `default_int_column` int(11) NOT NULL  AUTO_INCREMENT,
    ->     `zerofill_int_column` int(4) zerofill NOT NULL,
    ->     `not_zerofill_int_column` int(4) NOT NULL,
    ->     PRIMARY KEY (`default_int_column`)
    -> );
Query OK, 0 rows affected, 4 warnings (0.01 sec)

mysql> DESC sample;
+-------------------------+--------------------------+------+-----+---------+----------------+
| Field                   | Type                     | Null | Key | Default | Extra          |
+-------------------------+--------------------------+------+-----+---------+----------------+
| default_int_column      | int                      | NO   | PRI | NULL    | auto_increment |
| zerofill_int_column     | int(4) unsigned zerofill | NO   |     | NULL    |                |
| not_zerofill_int_column | int                      | NO   |     | NULL    |                |
+-------------------------+--------------------------+------+-----+---------+----------------+
3 rows in set (0.00 sec)

MySQL8.0.19以降はZEROFILL属性が付いている列とTINYINT(1)を除いて表示幅の指定が完全に無視されるようになっています。
MySQL 8.0.19リリースノート

まとめ

整数型の表示幅は、MySQL8.0.17から非推奨となり、8.0.19以降では一部を除いて無視されるようになりました。ZEROFILLも非推奨になっているので、データの見た目を制御したい場合は、LPAD()関数などで対応しましょう。

参考

MySQL :: MySQL Documentation

16
4
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
16
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?