1. 数据类型选择的重要性
数据类型在数据库中扮演着基础但很重要的角色,对数据类型的选择会影响与数据库交互的应用程序的性能,如果在数据库建表时选择了错误的类型,在后期维护中成本可能非常大,用户需要花大量时间来进行alter table操作。因此花一些时间学习一下这些基础,理解他们的基本原理是十分必要的。
选择数据类型要格外谨慎,因为在生产环境下更改数据类型可能是一项非常危险的操作。
2. unsigned 属性
unsigned就是将数字类型无符号化,与C、C++这些语言中的unsigned含义相同。
对于主键是自增长的类型大家一般是希望主键是非负数,但是在实际使用中unsigned可能会带来一些负面影响,示例如下:
mysql> create table t(a int unsigned, b int unsigned);
Query OK, 0 rows affected (0.06 sec)
mysql> insert into t select 1, 2;
Query OK, 1 row affected (0.10 sec)
Records: 1 Duplicates: 0 Warnings: 0
mysql> select * from t\G;
*************************** 1. row ***************************
a: 1
b: 2
1 row in set (0.04 sec)
运行如下语句:
select a -b from t;
如果sql_mode不严格此时的结果可能是不确定的。
sql_mode如果为严格模式则此种操作会报越界的异常:
mysql> select a - b from t;
ERROR 1690 (22003): BIGINT UNSIGNED value is out of range in '(`db1`.`t`.`a` - `db1`.`t`.`b`)'
此种现象,C语言场景下:
#include<stdio.h>
int main(){
unsigned int a;
unsigned int b;
a = 1;
b = 2;
printf("a - b:%d\n", a - b);
printf("a - b:%u\n", a - b);
return 0;
}
运行结果:
a - b:-1
a - b:4294967295
3. 总结
mysql数据库中unsigned数的操作结果都是unsigned的,解决此问题只需要将参数sql_mode进行如下设置即可:
mysql> set sql_mode='NO_UNSIGNED_SUBTRACTION';
Query OK, 0 rows affected (0.00 sec)
mysql> select a - b from t;
+-------+
| a - b |
+-------+
| -1 |
+-------+
1 row in set (0.00 sec)