三值逻辑(Three Value Logic)

在关系型数据库中,由于NULL值的存在,导致逻辑表达式存在三种值:TRUE/FALSE/UNKNOW。

SELECT
''=NULL AS C1,
''='' AS C2,
''='' AS C3; +------+----+----+
| C1 | C2 | C3 |
+------+----+----+
| NULL | 0 | 1 |
+------+----+----+
1 row in set (0.00 sec)

NULL值表示不确定或未知的值,因此NULL值是否等于或不等于某个特定值,只能使用IS NULL或IS NOT NULL来判断。

NULL值处理

在大部分场景中,NULL值不等于任何值包括NULL值,但在下列场景中设定NULL值相等:

1、对于唯一索引,仅允许唯一索引列存在一个NULL值。
2、对于GROUP BY和DISTINCT操作,所有NULL值当做同一组处理。
3、对于ORDER BY操作,所有NULL值被当做"最小值"排序在一起。

UNKNOW值处理

对于逻辑表达式计算后得到的UNKNOW值,在不同场景中处理方式不同:

1、在WHERE/ON/HAVING三类筛选操作中,UNKNOW值被当做FALSE处理。
2、在CHECK约束中,UNKNOW值被当做TRUE处理,CHECK约束仅对CHCK表达式为FALSE的记录返回错误。

UNKNOW值踩坑

很多生产案例是由于忽略UNKNOW值或对UNKNOW值处理不当导致,研发人员或DBA经常将逻辑表达式结果按照"非黑即白"(TURE OR FALSE)的结果去处理。

场景1、等值判断和不等值判断随意"转换",如:

表TB1表结构为(ID INT PRIMARY KEY,C1 VARCHAR(20))
A、查询满足C1等于'ABC'的记录,使用SELECT * FROM TB1 WHERE C1='ABC'
B、查询满足C1不等于'ABC'的记录,使用SELECT * FROM TB1 WHERE C1<>'ABC'
C、查询满足C1不等于'ABC'的记录,使用SELECT * FROM TB1 WHERE NOT(C1='ABC')
D、查询满足C1不等于'ABC'的记录,使用SELECT * FROM TB1 WHERE ID NOT IN (SELECT ID FROM TB1 WHERE C1='ABC')

如果表TB1上有C1列为NULL的记录,则上面操作B和操作C返回相同的查询结果,但操作B和操作D返回不同的查询结果,那么那个操作才真正满足业务需求呢?

场景2、IN子查询和NOT IN子查询随意“切换”, 如:

mysql.user表存放用户账号信息
A、使用 select host,user from mysql.user where user not in ('root')可以查出所有user不等于NULL且不等于root的账号。
A、使用select host,user from mysql.user where user not in ('root',NULL);不能查出所有user不等于ROOT和不等于NULL的用户,因为NOT IN条件中包含NULL,所有值包括NULL值在NOT IN(NULL)操作时,都会返回UNKNOW,因此该查询会返回空集。

MySQL NULL--三值逻辑(Three Value Logic)的更多相关文章

  1. MySQL的三值逻辑

    MySQL 采用三值逻辑 SELECT 1 = 1; SELECT 1 = 2; SELECT 1 = NULL; SELECT 1 != NULL; 上面四条语句的结果分别为: 可见MySQL采用三 ...

  2. MySQL NULL 值处理

    MySQL NULL 值处理 我们已经知道MySQL使用 SQL SELECT 命令及 WHERE 子句来读取数据表中的数据,但是当提供的查询条件字段为 NULL 时,该命令可能就无法正常工作. 为了 ...

  3. Oracle 与 Mysql NULL值,空字符串''的区别

    Oracle(null等同于空字符'') 1.oracle插入空字符串默认替换成null 2.oracle查询(null和被替换的空字符)时使用 is null/is not null 3.使用聚合函 ...

  4. 二十一、MySQL NULL 值处理

    MySQL NULL 值处理 我们已经知道 MySQL 使用 SQL SELECT 命令及 WHERE 子句来读取数据表中的数据,但是当提供的查询条件字段为 NULL 时,该命令可能就无法正常工作. ...

  5. DB-MySQL:MySQL NULL 值处理

    ylbtech-DB-MySQL:MySQL NULL 值处理 1.返回顶部 1. MySQL NULL 值处理 我们已经知道 MySQL 使用 SQL SELECT 命令及 WHERE 子句来读取数 ...

  6. MySQL NULL 使用带来的坑

    MySQL 基础篇 三范式 MySQL 军规 MySQL 配置 MySQL 用户管理和权限设置 MySQL 常用函数介绍 MySQL 字段类型介绍 MySQL 多列排序 MySQL 行转列 列转行 M ...

  7. mysql NULL函数 语法

    mysql NULL函数 语法 作用:如果表中的某个列是可选的,那么我们可以在不向该列添加值的情况下插入新记录或更新已有的记录.这意味着该字段将以 NULL 值保存. 说明:NULL 值的处理方式与其 ...

  8. mysql null值处理详细说明

    在讲null之前,我们先看一个例子 表数据如下: 3306>select * from t1; +------+-------+ | id | name | +------+-------+ | ...

  9. mysql=null的优雅解决方法

    对于不是采用所有字段都是not null的mysql表设计而言,mysql提供了一个<=>操作符. 在oracle中我们的处理方式通常类似: where a = #{var} or #{v ...

  10. mysql null值的特殊处理

    实例 尝试以下实例: root@host# mysql -u root -p password; Enter password:******* mysql> use RUNOOB; Databa ...

随机推荐

  1. Scrapy中的Request和Response

    Request Request 部分源码: # 部分代码 class Request(object_ref): def __init__(self, url, callback=None, metho ...

  2. server computer anaconda

    star@xmatrix:~/Anaconda$ star@xmatrix:~/Anaconda$ conda create -n wind1 python=3.6Solving environmen ...

  3. 《Effective Java》第1章 创建和销毁对象

    第1条 用静态工厂方法代替构造器 这个静态工厂,与设计模式中的静态工厂不同,这里的静态工厂方法,替换为“静态方法”比较好理解,主要就是建议编写静态方法来创建对象. 使用静态方法的好处: 1.静态方法有 ...

  4. 搭建npm私服流程

    npm私服必要性 1. 如果公司处于隐私保护的需要,不想将自己封的包推到npm社区,但又急需要一套完整的包管理工具来管理越来越多的组件,模块,项目.对于前端,最熟悉的莫过于npm,bower等,但是b ...

  5. vSphere SDK for Java - 为虚拟机添加磁盘

    示例代码: import com.vmware.vim25.*; import com.vmware.vim25.mo.*; import org.springframework.stereotype ...

  6. iOS - 截取数组前几个元素放入新的数组,剩余的放入另外一个数组

    NSArray *array = [NSArray arrayWithObjects:@"Crystal",@"Maisie",@"Lukas&quo ...

  7. 硬盘分区及Linux文件系统

    1. 硬盘物理结构 硬盘物理上主要分为: 盘片 磁道 扇区 机械臂 磁头 主轴 磁道: 当硬盘盘片旋转时,磁头若固定在一个位置上,则磁头会在盘片表面划出一个圆形轨迹,这些圆形轨迹就叫做磁道.以盘片中心 ...

  8. Mac home目录下,创建文件夹,修改权限

    http://php-note.com/article/detail/35e782e145a94042923946cb142b5cd1 1.关闭 SIP 2.sudo mount -uw /

  9. 【Spring Boot学习之五】切面日志管理

    环境 eclipse 4.7 jdk 1.8 Spring Boot 1.5.2 一.log4j 常见方式:log4j.properties + org.apache.log4j.Logger比如:l ...

  10. my97整合fineui例子,开始和结束时间

      <f: Toolbar runat ="server">                             <Items>             ...