为什么 tinyint 的长度似乎没有区别?

为什么 tinyint 的长度似乎没有区别?

我一直在寻找tinyint声明中的长度是什么意思(例如tinyint(5))。答案似乎是它应该只是 MySQL 显示数据的规则。但就我而言,无论我使用哪种长度,似乎都没有变化,或者我只是严重误解了它们的含义。

例如,将长度设置为比我存储的数字的长度短,我以为它可能会裁剪它,但没有:

MariaDB [test]> describe test;
+-------+------------+------+-----+---------+-------+
| Field | Type       | Null | Key | Default | Extra |
+-------+------------+------+-----+---------+-------+
| hello | tinyint(1) | NO   |     | NULL    |       |
+-------+------------+------+-----+---------+-------+
1 row in set (0.002 sec)

MariaDB [test]> select * from test;
+-------+
| hello |
+-------+
|    20 |
+-------+
1 row in set (0.000 sec)

然后我将长度改为比数字的长度更长,希望它用零填充到左边,但事实并非如此:

MariaDB [test]> describe test;
+-------+------------+------+-----+---------+-------+
| Field | Type       | Null | Key | Default | Extra |
+-------+------------+------+-----+---------+-------+
| hello | tinyint(3) | NO   |     | NULL    |       |
+-------+------------+------+-----+---------+-------+
1 row in set (0.002 sec)

MariaDB [test]> select * from test;
+-------+
| hello |
+-------+
|    20 |
+-------+
1 row in set (0.001 sec)

我使用的版本是:5.5.5-10.3.25-MariaDB-0ubuntu

我如何才能看出这个长度声明有何不同?

答案1

在 SQL 中,INTEGER类型不是由数字位数定义的。而是声明可用于表示值的字节数。例如,如果您定义一个,TINYINT(1)您将获得一个字节来存储数字。

-128对于有符号整数,这将为您提供到的范围,127而对于无符号整数,您将获得到的0范围255

create table test (signed_tiny tinyint(1), unsigned_tiny tinyint(1) unsigned);
insert into test (signed_tiny, unsigned_tiny) values (-128, 0), (127, 255);
select * from test;
+-------------+---------------+
| signed_tiny | unsigned_tiny |
+-------------+---------------+
|        -128 |             0 |
|         127 |           255 |
+-------------+---------------+
2 rows in set (0.00 sec)

当您尝试插入超出这些范围的值时,您将收到一条错误消息:

insert into test (signed_tiny, unsigned_tiny) values (128, 256);
ERROR 1264 (22003): Out of range value for column 'signed_tiny' at row 1

如果你在括号内声明一个更高的数字,这并没有什么区别,TINYINT因为它被静态定义为一个字节,所以仍然会得到相同的错误,例如

alter table test modify signed_tiny tinyint(2);
insert into test (signed_tiny) values (128);
ERROR 1264 (22003): Out of range value for column 'signed_tiny' at row 1

为了避免此错误,您可以使用SMALLINT定义为使用两个字节来表示值或使用标准 SQLINT数据类型:

alter table test add signed_smallint smallint;
insert into test (signed_smallint) values (128);
Query OK, 1 row affected (0.02 sec)

根据MariaDB TINYINT 手册您可以在括号中添加数字,但这不会产生任何影响。因此,TINYINT在 MySQL 和 MariaDB 中, 是标准 SQL 的别名INT(1), 是SMALLINT的另一个别名INT(2)

我希望这能让你更清楚一点。无论如何,我建议你看一下MariaDB 文档。

答案2

(5)无用的信息,除非与 结合ZEROFILL。它是无害的。

MySQL 8.0.19 已删除这两者。MariaDB可能几年后也将效仿。

FLOAT(m,n)确实有意义,但我认为应该绝不被使用。可以说它是有害的。(8.0.17 已弃用它。)

同时,现在是时候超越 5.5 版本了。

相关内容