![为什么 tinyint 的长度似乎没有区别?](https://linux22.com/image/760446/%E4%B8%BA%E4%BB%80%E4%B9%88%20tinyint%20%E7%9A%84%E9%95%BF%E5%BA%A6%E4%BC%BC%E4%B9%8E%E6%B2%A1%E6%9C%89%E5%8C%BA%E5%88%AB%EF%BC%9F.png)
我一直在寻找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 版本了。