• 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,因此该查询会返回空集。
  • 相关阅读:
    linq语法2 GLenn
    sql 拼接字符串 GLenn
    每日算法 20130225 GLenn
    linq语法1 GLenn
    每日算法 20130227 GLenn
    每日算法 20130226 GLenn
    jquery ajax 分页 GLenn
    PhoneGap应用开发对策:如何通过苹果审核?
    Xcode 4.1/4.2/4.3/4.4/4.5 + iOS 5.1.1免证书(iDP)开发+真机调试+生成IPA全攻略
    rails 散乱记录
  • 原文地址:https://www.cnblogs.com/gaogao67/p/11324365.html
Copyright © 2020-2023  润新知