三值逻辑(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. pipeline配置sonar和自动化

    1.sonar配置webhooks, 2.url填写jenkins的地址:http://jenkinsurl/sonarqube-webhook/ 3.前提:jenkins配置好sonar的scann ...

  2. Spring Shell入门介绍

    目录 Spring Shell是什么 入门实践 基础配置 简单示例 注解@ShellMethod 注解@ShellOption 自定义参数名称 设置参数默认值 为一个参数传递多个值 对布尔参数的特殊处 ...

  3. Linux学习、Mongodb部署 踩到的坑学习

    一.安装Centos 7虚拟机系统 1.系统安装 下载阿里云的镜像,下载后安装,默认全程图形界面:虚拟机使用Win10自带的Hyper:碰到的坑记录下 1.在Hyper加载镜像启动的时候,提示“虚拟机 ...

  4. java-工厂

    class Mouse{ public void sayHi(){}; } class DellMouse extends Mouse { @Override public void sayHi() ...

  5. linux安装Elasticsearch详细步骤

    坑都已经踩好了 照着步骤一次成功  不多废话 走起 # ## 安装java运行环境 elasticsearch是用Java实现的 跑elasticsearch必须要有jre支持 所以必须先安装jre ...

  6. delphi10.2断点调试dll

    因为工作需要接触delphi10.2,需要调试dll,但是从网上查找的资料写的不是很清楚,我折腾了半天,我就动手写清楚操作步骤: 步骤1:用delphi10.2打开需要调试的dll,需要先打开,然后需 ...

  7. LocalStack和Local对象实现栈的管理

    flask里面有两个重要的类Local和LocalStack 输入from flask import globals 左键+ctrl点globals进入源码,进去后找57行 flask只会实例化出这两 ...

  8. kali更新软件源

    首先就是修改软件源文件 /etc/apt/sources.list 可以用leafpad打开,在终端中键入: leafpad /etc/apt/sources.list 原码是kali官方的软件源,更 ...

  9. Dubbo使用javassist生成动态类

    在服务(本地和远程)暴露的时候会调用proxyFactory.getInvoker方法 具体位置: 本地暴露:ServiceConfig#exportLocal line:538 远程暴露: Serv ...

  10. 查看Linux服务器配置

    1.查看CPU lscpu 2.查看内存 free -g 或 free -m 3.查看硬盘 df -h