zoukankan      html  css  js  c++  java
  • mysql中的null字段值的处理及大小写问题

    在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。

    1 mysql> use test
    2 Database changed
    3 mysql> show tables;
    4 Empty set (0.00 sec)
    5 
    6 mysql> create table checknull(
    7     -> name varchar(30) not null,
    8     -> age int);
    9 Query OK, 0 rows affected (0.11 sec)

    我们看看这个表的创建基本信息,用show和desc分别查看:

     1 mysql> show create table checknull;
     2 +-----------+-------------------------------------------------------------------------------------------------------------------------------+
     3 | Table     | Create Table                                                                                                                  |
     4 +-----------+-------------------------------------------------------------------------------------------------------------------------------+
     5 | checknull | CREATE TABLE `checknull` (
     6   `name` varchar(30) NOT NULL,
     7   `age` int(11) DEFAULT NULL
     8 ) ENGINE=MyISAM DEFAULT CHARSET=latin1 |
     9 +-----------+-------------------------------------------------------------------------------------------------------------------------------+
    10 1 row in set (0.01 sec)
    11 
    12 mysql> desc checknull;
    13 +-------+-------------+------+-----+---------+-------+
    14 | Field | Type        | Null | Key | Default | Extra |
    15 +-------+-------------+------+-----+---------+-------+
    16 | name  | varchar(30) | NO   |     | NULL    |       |
    17 | age   | int(11)     | YES  |     | NULL    |       |
    18 +-------+-------------+------+-----+---------+-------+
    19 2 rows in set (0.00 sec)

    我们开始测试一下,第一步,向这个表中插入数据:

     1 mysql> insert checknull (name, age) values("water", 30);
     2 Query OK, 1 row affected (0.00 sec)
     3 
     4 mysql> 
     5 mysql> insert checknull (name, age) values("shihuc", NULL);
     6 Query OK, 1 row affected (0.00 sec)
     7 
     8 mysql> 
     9 mysql> select * from checknull;
    10 +--------+------+
    11 | name   | age  |
    12 +--------+------+
    13 | water  |   30 |
    14 | shihuc | NULL |
    15 +--------+------+
    16 2 rows in set (0.00 sec)

    接下来,再查询看看,先查询所有的age字段是NULL的用户信息:

     1 mysql> select * from checknull where age = NULL;
     2 Empty set (0.00 sec)
     3 
     4 mysql> select * from checknull where age IS NULL;
     5 +--------+------+
     6 | name   | age  |
     7 +--------+------+
     8 | shihuc | NULL |
     9 +--------+------+
    10 1 row in set (0.00 sec)
     1 mysql> select * from checknull where age != NULL;
     2 Empty set (0.00 sec)
     3 
     4 mysql> select * from checknull where age IS NOT NULL;
     5 +-------+------+
     6 | name  | age  |
     7 +-------+------+
     8 | water |   30 |
     9 +-------+------+
    10 1 row in set (0.00 sec)

    是不是发现,结果不同?那么我现在,通过修改大小写来查看查询结果:

     1 mysql> select * from checknull where age IS null;
     2 +--------+------+
     3 | name   | age  |
     4 +--------+------+
     5 | shihuc | NULL |
     6 +--------+------+
     7 1 row in set (0.00 sec)
     8 
     9 mysql> select * from checknull where age = null;
    10 Empty set (0.00 sec)
     1 mysql> select * from checknull where age != null;
     2 Empty set (0.00 sec)
     3 
     4 mysql> select * from checknull where age is not null;
     5 +-------+------+
     6 | name  | age  |
     7 +-------+------+
     8 | water |   30 |
     9 +-------+------+
    10 1 row in set (0.00 sec)

    发现结果和上面的日志反映的内容一样。

    这里补充一个小tips,那就是在Linux下,mysql默认情况下,数据库的名字,表的名字和字段的名字是区分大小写的,但是字段的值是不区分大小写的。表的名字和字段的名字是否区分大小写,可以查看数据库变量lower_case_table_names的值,0表示区分大小写;1表示不区分,统一按照小写对待。

    1 mysql> show variables like "%case%";
    2 +------------------------+-------+
    3 | Variable_name          | Value |
    4 +------------------------+-------+
    5 | lower_case_file_system | OFF   |
    6 | lower_case_table_names | 0     |
    7 +------------------------+-------+
    8 2 rows in set (0.00 sec)

    而对于字段的值,想要区分大小写,可以使用BINARY加以限制。不管是在创建表的时候,还是在查询的条件字句中都可以使用。

     1 mysql> create table lowupper(
     2     -> name varchar(30) not null,
     3     -> age int,
     4     -> home varchar(40) binary);
     5 Query OK, 0 rows affected (0.10 sec)
     6 
     7 mysql> show create table lowupper;
     8 +----------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
     9 | Table    | Create Table                                                                                                                                                                                            |
    10 +----------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
    11 | lowupper | CREATE TABLE `lowupper` (
    12   `name` varchar(30) NOT NULL,
    13   `age` int(11) DEFAULT NULL,
    14   `home` varchar(40) CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL
    15 ) ENGINE=MyISAM DEFAULT CHARSET=latin1 |
    16 +----------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
    17 1 row in set (0.00 sec)

    上面日志中,可以看到,创建表的时候,在home字段后面加了约束binary,通过show可以看到,home字段有一个校对规则 latin1_bin,说明,这个会在插入/查询数据的时候是区分大小写的。

    下面插入数据做些验证:

     1 mysql> insert lowupper (name, age, home) values ("shihuc", 30, "Beijing, china");
     2 Query OK, 1 row affected (0.00 sec)
     3 
     4 mysql> 
     5 mysql> insert lowupper (name, age, home) values ("water", 33, "BEIJING, china");
     6 Query OK, 1 row affected (0.00 sec)
     7 
     8 mysql> insert lowupper (name, age, home) values ("xiaocheng", 33, "hubei");
     9 Query OK, 1 row affected (0.00 sec)
    10 
    11 mysql> insert lowupper (name, age, home) values ("zhangsan", null, "china");
    12 Query OK, 1 row affected (0.00 sec)
    13 
    14 mysql> insert lowupper (name, age, home) values ("lisi", null, "CHINA");
    15 Query OK, 1 row affected (0.00 sec)
    16 
    17 mysql> insert lowupper (name, age, home) values ("wangwu", null, "China");
    18 Query OK, 1 row affected (0.00 sec)
    19 
    20 mysql> select * from lowupper;
    21 +-----------+------+----------------+
    22 | name      | age  | home           |
    23 +-----------+------+----------------+
    24 | shihuc    |   30 | Beijing, china |
    25 | water     |   33 | BEIJING, china |
    26 | xiaocheng |   33 | hubei          |
    27 | zhangsan  | NULL | china          |
    28 | lisi      | NULL | CHINA          |
    29 | wangwu    | NULL | China          |
    30 +-----------+------+----------------+
    31 6 rows in set (0.00 sec)

    下面,再查询一下看看,是否有区分:

    1 mysql> select * from lowupper where home = "china";
    2 +----------+------+-------+
    3 | name     | age  | home  |
    4 +----------+------+-------+
    5 | zhangsan | NULL | china |
    6 +----------+------+-------+
    7 1 row in set (0.00 sec)

    再操作上面checknull表,在其中插入一条新的数据,进行查询,看是否区分大小写:

     1 mysql> insert checknull (name, age) values ("SHIHUC", null);
     2 Query OK, 1 row affected (0.00 sec)
     3 
     4 mysql> select * from checknull;
     5 +--------+------+
     6 | name   | age  |
     7 +--------+------+
     8 | water  |   30 |
     9 | shihuc | NULL |
    10 | SHIHUC | NULL |
    11 +--------+------+
    12 3 rows in set (0.00 sec)
    13 
    14 mysql> select * from checknull where name = "shihuc";
    15 +--------+------+
    16 | name   | age  |
    17 +--------+------+
    18 | shihuc | NULL |
    19 | SHIHUC | NULL |
    20 +--------+------+
    21 2 rows in set (0.00 sec)
    22 
    23 mysql> select * from checknull where binary name = "shihuc";
    24 +--------+------+
    25 | name   | age  |
    26 +--------+------+
    27 | shihuc | NULL |
    28 +--------+------+
    29 1 row in set (0.00 sec)

    是不是很显然的,说明MySQL的大小写问题,还是很有意思的,需要注意,在linux环境下。windows环境下,没有测试,不是很确定。有经验的可以分享一下!

  • 相关阅读:
    线上查询及帮助命令:
    windows: 2.7 3.5 (主要)
    get the execution time of a sql statement.
    java-kafka安装以及使用案例
    java-黑马头条 weex前端路由
    MYSQL安装
    缓存
    Flask中current_app和g对象
    [ValueError: signal only works in main thread]
    Flask-SQLAlchemy操作
  • 原文地址:https://www.cnblogs.com/shihuc/p/5165169.html
Copyright © 2011-2022 走看看