mysql中的null字段值的处理及大小写问题
2016-01-28 09:13
441 查看
在MySQL中,NULL字段的处理,需要注意,当在处理查询条件中有NULL,很有可能你得到的值不是想要的,因为,在MySQL中,判断NULL值相等(=)或者不等(!=)都会返回false。主要出现在常见的SELECT以及WHERE字句中。
为了处理这种特殊的情况,MySQL提供了如下的关键字进行特殊处理:
IS NULL: 当列的值是NULL,此运算符返回true。
IS NOT NULL: 当列的值不为NULL, 运算符返回true。
<=>: 比较操作符(不同于=运算符),当比较的的两个值为NULL时返回true。
关于 NULL 的条件比较运算是比较特殊的。你不能使用 = NULL 或 != NULL 在列中查找 NULL 值 。在MySQL中,NULL值与任何其它值的比较(即使是NULL)永远返回false,即 NULL = NULL 返回false 。
下面看看例子,就很清楚的理解是什么意思了。
先在test数据库中创建一个表checknull。
我们看看这个表的创建基本信息,用show和desc分别查看:
我们开始测试一下,第一步,向这个表中插入数据:
接下来,再查询看看,先查询所有的age字段是NULL的用户信息:
是不是发现,结果不同?那么我现在,通过修改大小写来查看查询结果:
发现结果和上面的日志反映的内容一样。
这里补充一个小tips,那就是在Linux下,mysql默认情况下,数据库的名字,表的名字和字段的名字是区分大小写的,但是字段的值是不区分大小写的。表的名字和字段的名字是否区分大小写,可以查看数据库变量lower_case_table_names的值,0表示区分大小写;1表示不区分,统一按照小写对待。
而对于字段的值,想要区分大小写,可以使用BINARY加以限制。不管是在创建表的时候,还是在查询的条件字句中都可以使用。
上面日志中,可以看到,创建表的时候,在home字段后面加了约束binary,通过show可以看到,home字段有一个校对规则 latin1_bin,说明,这个会在插入/查询数据的时候是区分大小写的。
下面插入数据做些验证:
下面,再查询一下看看,是否有区分:
再操作上面checknull表,在其中插入一条新的数据,进行查询,看是否区分大小写:
是不是很显然的,说明MySQL的大小写问题,还是很有意思的,需要注意,在linux环境下。windows环境下,没有测试,不是很确定。有经验的可以分享一下!
为了处理这种特殊的情况,MySQL提供了如下的关键字进行特殊处理:
IS NULL: 当列的值是NULL,此运算符返回true。
IS NOT NULL: 当列的值不为NULL, 运算符返回true。
<=>: 比较操作符(不同于=运算符),当比较的的两个值为NULL时返回true。
关于 NULL 的条件比较运算是比较特殊的。你不能使用 = NULL 或 != NULL 在列中查找 NULL 值 。在MySQL中,NULL值与任何其它值的比较(即使是NULL)永远返回false,即 NULL = NULL 返回false 。
下面看看例子,就很清楚的理解是什么意思了。
先在test数据库中创建一个表checknull。
mysql> use test Database changed mysql> show tables; Empty set (0.00 sec) mysql> create table checknull( -> name varchar(30) not null, -> age int); Query OK, 0 rows affected (0.11 sec)
我们看看这个表的创建基本信息,用show和desc分别查看:
mysql> show create table checknull; +-----------+-------------------------------------------------------------------------------------------------------------------------------+ | Table | Create Table | +-----------+-------------------------------------------------------------------------------------------------------------------------------+ | checknull | CREATE TABLE `checknull` ( `name` varchar(30) NOT NULL, `age` int(11) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 | +-----------+-------------------------------------------------------------------------------------------------------------------------------+ 1 row in set (0.01 sec) mysql> desc checknull; +-------+-------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-------+-------------+------+-----+---------+-------+ | name | varchar(30) | NO | | NULL | | | age | int(11) | YES | | NULL | | +-------+-------------+------+-----+---------+-------+ 2 rows in set (0.00 sec)
我们开始测试一下,第一步,向这个表中插入数据:
mysql> insert checknull (name, age) values("water", 30); Query OK, 1 row affected (0.00 sec) mysql> mysql> insert checknull (name, age) values("shihuc", NULL); Query OK, 1 row affected (0.00 sec) mysql> mysql> select * from checknull; +--------+------+ | name | age | +--------+------+ | water | 30 | | shihuc | NULL | +--------+------+ 2 rows in set (0.00 sec)
接下来,再查询看看,先查询所有的age字段是NULL的用户信息:
mysql> select * from checknull where age = NULL; Empty set (0.00 sec) mysql> select * from checknull where age IS NULL; +--------+------+ | name | age | +--------+------+ | shihuc | NULL | +--------+------+ 1 row in set (0.00 sec)
mysql> select * from checknull where age != NULL; Empty set (0.00 sec) mysql> select * from checknull where age IS NOT NULL; +-------+------+ | name | age | +-------+------+ | water | 30 | +-------+------+ 1 row in set (0.00 sec)
是不是发现,结果不同?那么我现在,通过修改大小写来查看查询结果:
mysql> select * from checknull where age IS null; +--------+------+ | name | age | +--------+------+ | shihuc | NULL | +--------+------+ 1 row in set (0.00 sec) mysql> select * from checknull where age = null; Empty set (0.00 sec)
mysql> select * from checknull where age != null; Empty set (0.00 sec) mysql> select * from checknull where age is not null; +-------+------+ | name | age | +-------+------+ | water | 30 | +-------+------+ 1 row in set (0.00 sec)
发现结果和上面的日志反映的内容一样。
这里补充一个小tips,那就是在Linux下,mysql默认情况下,数据库的名字,表的名字和字段的名字是区分大小写的,但是字段的值是不区分大小写的。表的名字和字段的名字是否区分大小写,可以查看数据库变量lower_case_table_names的值,0表示区分大小写;1表示不区分,统一按照小写对待。
mysql> show variables like "%case%"; +------------------------+-------+ | Variable_name | Value | +------------------------+-------+ | lower_case_file_system | OFF | | lower_case_table_names | 0 | +------------------------+-------+ 2 rows in set (0.00 sec)
而对于字段的值,想要区分大小写,可以使用BINARY加以限制。不管是在创建表的时候,还是在查询的条件字句中都可以使用。
mysql> create table lowupper( -> name varchar(30) not null, -> age int, -> home varchar(40) binary); Query OK, 0 rows affected (0.10 sec) mysql> show create table lowupper; +----------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | Table | Create Table | +----------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | lowupper | CREATE TABLE `lowupper` ( `name` varchar(30) NOT NULL, `age` int(11) DEFAULT NULL, `home` varchar(40) CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 | +----------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ 1 row in set (0.00 sec)
上面日志中,可以看到,创建表的时候,在home字段后面加了约束binary,通过show可以看到,home字段有一个校对规则 latin1_bin,说明,这个会在插入/查询数据的时候是区分大小写的。
下面插入数据做些验证:
mysql> insert lowupper (name, age, home) values ("shihuc", 30, "Beijing, china"); Query OK, 1 row affected (0.00 sec) mysql> mysql> insert lowupper (name, age, home) values ("water", 33, "BEIJING, china"); Query OK, 1 row affected (0.00 sec) mysql> insert lowupper (name, age, home) values ("xiaocheng", 33, "hubei"); Query OK, 1 row affected (0.00 sec) mysql> insert lowupper (name, age, home) values ("zhangsan", null, "china"); Query OK, 1 row affected (0.00 sec) mysql> insert lowupper (name, age, home) values ("lisi", null, "CHINA"); Query OK, 1 row affected (0.00 sec) mysql> insert lowupper (name, age, home) values ("wangwu", null, "China"); Query OK, 1 row affected (0.00 sec) mysql> select * from lowupper; +-----------+------+----------------+ | name | age | home | +-----------+------+----------------+ | shihuc | 30 | Beijing, china | | water | 33 | BEIJING, china | | xiaocheng | 33 | hubei | | zhangsan | NULL | china | | lisi | NULL | CHINA | | wangwu | NULL | China | +-----------+------+----------------+ 6 rows in set (0.00 sec)
下面,再查询一下看看,是否有区分:
mysql> select * from lowupper where home = "china"; +----------+------+-------+ | name | age | home | +----------+------+-------+ | zhangsan | NULL | china | +----------+------+-------+ 1 row in set (0.00 sec)
再操作上面checknull表,在其中插入一条新的数据,进行查询,看是否区分大小写:
mysql> insert checknull (name, age) values ("SHIHUC", null); Query OK, 1 row affected (0.00 sec) mysql> select * from checknull; +--------+------+ | name | age | +--------+------+ | water | 30 | | shihuc | NULL | | SHIHUC | NULL | +--------+------+ 3 rows in set (0.00 sec) mysql> select * from checknull where name = "shihuc"; +--------+------+ | name | age | +--------+------+ | shihuc | NULL | | SHIHUC | NULL | +--------+------+ 2 rows in set (0.00 sec) mysql> select * from checknull where binary name = "shihuc"; +--------+------+ | name | age | +--------+------+ | shihuc | NULL | +--------+------+ 1 row in set (0.00 sec)
是不是很显然的,说明MySQL的大小写问题,还是很有意思的,需要注意,在linux环境下。windows环境下,没有测试,不是很确定。有经验的可以分享一下!
相关文章推荐
- 深入mysql "ON DUPLICATE KEY UPDATE" 语法的分析
- mysql 5.7.10安装配置
- mysql5.7.10安装
- MySQL恢复中的几个问题解决方法
- MySQL性能优化的最佳经验
- Mysql 表分区
- mysql加入行号
- mysql汉字首字母
- mysql 替换某个字段中的某个字符
- Cent OS 7 安装 mysql-5.7
- mysql root修改密码
- MySql索引算法原理解析(通俗易懂,只讲B-tree)
- mysql 5.7.7以后需要初始化数据库
- MySql数据库(二)
- MySQL执行状态分析
- MySql数据库(一)
- mysql 语句中带变量
- mysql explain详解
- MySQL 5.5 服务器变量详解(一)
- mysql查询当前用户