zoukankan      html  css  js  c++  java
  • MySQL NULL--三值逻辑(Three Value Logic)

    三值逻辑(Three Value Logic)

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

    SELECT 
    '999'=NULL AS C1,
    '999'='111' AS C2,
    '999'='999' 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,因此该查询会返回空集。
  • 相关阅读:
    014.Nginx跨域配置
    013.Nginx动静分离
    附002.Nginx代理相关模块解析
    附001.Nginx location语法规则
    016.Nginx HTTPS
    015.Nginx重定向
    Blazor带我重玩前端(四)
    数据结构中的树(二叉树、二叉搜索树、AVL树)
    Flask前后端分离项目案例
    LeetCode-位运算相关题解
  • 原文地址:https://www.cnblogs.com/gaogao67/p/11324365.html
Copyright © 2011-2022 走看看