什么是MySQL中的“unsigned”,何时使用它?
在MySQL中,unsigned是一种数据类型修饰符,用来限定一个整数的范围。如果一个整数字段被声明为unsigned,那么它就不能被赋予负数值,它只能存储非负整数值。这意味着,如果我们定义了一个unsigned整数类型,并且将一个负数存储到这个字段中,那么实际上它可能会被转换成另一个正数值。
unsigned主要用于限制整数的大小范围、提高数据字段的存储空间和优化查询性能等方面。接下来我们将分别介绍这些方面。
阅读更多:MySQL 教程
限制整数的大小范围
MySQL的整数类型包括:TINYINT、SMALLINT、MEDIUMINT、INT、BIGINT等等。这些整数类型能够存储的数据范围是有限制的,如下表所示:
数据类型 | 最小值 | 最大值 |
---|---|---|
TINYINT | -128 | 127 |
TINYINT UNSIGNED | 0 | 255 |
SMALLINT | -32768 | 32767 |
SMALLINT UNSIGNED | 0 | 65535 |
MEDIUMINT | -8388608 | 8388607 |
MEDIUMINT UNSIGNED | 0 | 16777215 |
INT | -2147483648 | 2147483647 |
INT UNSIGNED | 0 | 4294967295 |
BIGINT | -9223372036854775808 | 9223372036854775807 |
BIGINT UNSIGNED | 0 | 18446744073709551615 |
从上表可以看出,有些数据类型可以存储负整数,有些则不行。如果我们需要存储大于或等于零的整数,就可以使用unsigned修饰符。例如,我们对一个INT类型的字段添加unsigned修饰符后,可以将字段的最大值增加到4294967295,该值还是远远超过了一般应用场景下需要的最大整数值,可以满足绝大部分应用场景下的需求。
提高数据字段的存储空间
有一些数据类型,在加上unsigned修饰符后,其占用空间会比原来的类型更小。比如,在TINYINT和SMALLINT类型的字段中添加unsigned修饰符后,它们的存储空间分别减少了一个字节。这块空间的节省可能在某些情况下很有用,可以节省硬盘存储空间和减少索引文件的大小等。
为了更好的说明这一点,下面我们来比较一下添加和不添加unsigned修饰符所需占用的空间。
mysql> CREATE TABLE demo (
-> id INT NOT NULL,
-> id_unsigned INT UNSIGNED NOT NULL
-> );
Query OK, 0 rows affected (0.05 sec)
在上面的代码中,我们创建了一个名为demo的表,该表包含两个id字段,一个不带unsigned修饰符,另一个带有unsigned修饰符。我们将通过下面的语句来查看两个id字段需要占用的存储空间:
mysql> SHOW CREATE TABLE demo \G
*************************** 1. row ***************************
Table: demo
Create Table: CREATE TABLE `demo` (
`id` int NOT NULL,
`id_unsigned` int(10) unsigned NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
1 row in set (0.00 sec)
从上面的查询结果中可以看出,带有unsigned修饰符的id_unsigned字段所占的存储空间仅为4个字节,而不带unsigned修饰符的id字段占用的存储空间为4个字节。这意味着,在不使用unsigned修饰符的情况下,同样大小的硬盘空间只能存储一半的id数据。
优化查询性能
在使用unsigned修饰符时,可能会在某些情况下提高查询性能。这是因为在进行索引扫描时,如果使用的是带有unsigned修饰符的整数类型,一些比较操作将变得更快,并且MySQL可能会更加有效地使用索引。这主要是因为MySQL可以将无符号整数类型与带符号整数类型进行比较,而不需要进行转换,这将显著降低比较的开销。例如,在下面的代码中,我们比较了两个字段并计算了它们的SUM值:
mysql> SELECT SUM(id), SUM(id_unsigned) FROM demo;
在上面的代码中,SUM函数将对id和id_unsigned字段进行相加,并返回它们的总和。但是,在计算这个总和之前,我们需要对每个整数进行自己的符号转换,并在比较两个数据时进行相应的转换。如果我们在这个查询中使用了unsigned修饰符,MySQL可以在不进行这些转换的情况下直接对整数进行比较,这将提高查询效率。
结论
在MySQL中,unsigned是一种数据类型修饰符,它用于限制整数的范围、提高数据字段的存储空间和优化查询性能等。在选择是否使用unsigned时,应该考虑到整数的符号性、数据范围、存储空间大小以及带unsigned修饰符的整数类型与带符号整数类型进行比较时所需的转换等因素。