三种类型的数据库下面分别创建对应的测试表:

--Oracle 11.2
CREATE TABLE t_oracle (id int ,name varchar2(10),dept varchar2(20) not null);
--MySQL 5.7CREATE TABLE t_mysql (id int ,name varchar(10),dept varchar(20) not null); --TiDB  3.0CREATE TABLE t_tidb (id int ,name varchar(10),dept varchar(20) not null); 

插入数据测试:

先说结论:oracle把''作为空值(null)处理;mysql和tidb是作为空字符串处理,''不是null值。

--oracle

insert into t_oracle values(1,'test','depttest');
insert into t_oracle values(2,'','depttest');
insert into t_oracle values(3,null,'depttest');
insert into t_oracle values(4,null,'');
commit;

结果如下:第四行插入失败,oracle把''作为空值处理

18:02:35 SYS@orcl11g>insert into t_oracle values(1,'test','depttest');1 row created.11:09:39 SYS@orcl11g>insert into t_oracle values(2,'','depttest');1 row created.11:09:39 SYS@orcl11g>insert into t_oracle values(3,null,'depttest');1 row created.11:09:39 SYS@orcl11g>insert into t_oracle values(4,null,'');
insert into t_oracle values(4,null,'')*
ERROR at line 1:
ORA-01400: cannot insert NULL into ("SYS"."T_ORACLE"."DEPT")11:09:39 SYS@orcl11g>commit;Commit complete.

--mysql

insert into t_mysql values(1,'test','depttest');
insert into t_mysql values(2,'','depttest');
insert into t_mysql values(3,null,'depttest');
insert into t_mysql values(4,null,'');

结果如下:都可以成功插入数据

11:13:31[5.7.25-log]root->127.0.0.1[mtest]> insert into t_mysql values(1,'test','depttest');
Query OK, 1 row affected (0.01 sec)11:13:38[5.7.25-log]root->127.0.0.1[mtest]> insert into t_mysql values(2,'','depttest');
insert into t_mysql values(3,null,'depttest');
Query OK, 1 row affected (0.01 sec)11:13:38[5.7.25-log]root->127.0.0.1[mtest]> insert into t_mysql values(3,null,'depttest');
Query OK, 1 row affected (0.01 sec)11:13:38[5.7.25-log]root->127.0.0.1[mtest]> insert into t_mysql values(4,null,'');
Query OK, 1 row affected (0.00 sec)11:13:38[5.7.25-log]root->127.0.0.1[mtest]> 

--tidb

insert into t_tidb values(1,'test','depttest');
insert into t_tidb values(2,'','depttest');
insert into t_tidb values(3,null,'depttest');
insert into t_tidb values(4,null,'');

结果如下:都可以成功插入数据

11:15:38[5.7.25-TiDB-v3.0.17]root->192.168.30.11[mtest]> insert into t_tidb values(1,'test','depttest');
insert into t_tidb values(2,'','depttest');
insert into t_tidb values(3,null,'depttest');
insert into t_tidb values(4,null,'');
Query OK, 1 row affected (0.07 sec)11:15:40[5.7.25-TiDB-v3.0.17]root->192.168.30.11[mtest]> insert into t_tidb values(2,'','depttest');
Query OK, 1 row affected (0.02 sec)11:15:40[5.7.25-TiDB-v3.0.17]root->192.168.30.11[mtest]> insert into t_tidb values(3,null,'depttest');
Query OK, 1 row affected (0.03 sec)11:15:40[5.7.25-TiDB-v3.0.17]root->192.168.30.11[mtest]> insert into t_tidb values(4,null,'');
Query OK, 1 row affected (0.02 sec)11:15:40[5.7.25-TiDB-v3.0.17]root->192.168.30.11[mtest]> 

空值(null) 转换处理

--oracle
select id,nvl(name,id),dept from t_oracle;
--mysql、tidb
select id,ifnull(name,id),dept from t_mysql;

空值(null)过滤筛选

在name列上分别创建索引

--oracle
create index idx_1 on t_oracle(name);
--mysql
create index idx_1 on t_mysql(name);
--tidb
create index idx_1 on t_tidb(name);

验证下筛选条件上有空值的过滤是否会走索引

先造一些测试数据,不同数据库相关表名替换下

for i in $(seq 1 100000)
doecho "insert into t_oracle values($(($RANDOM%1000)),'test${i}','depttest');" >> t.sql
done
--oracle,全表扫描
set autotrace on
set timing on
select * from t_oracle where name is null;ID NAME       DEPT
---------- ---------- --------------------2            depttest3            depttestElapsed: 00:00:00.01Execution Plan
----------------------------------------------------------
Plan hash value: 286026154------------------------------------------------------------------------------
| Id  | Operation         | Name     | Rows  | Bytes | Cost (%CPU)| Time     |
------------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |          |     1 |    32 |     2   (0)| 00:00:01 |
|*  1 |  TABLE ACCESS FULL| T_ORACLE |     1 |    32 |     2   (0)| 00:00:01 |
------------------------------------------------------------------------------Predicate Information (identified by operation id):
---------------------------------------------------1 - filter("NAME" IS NULL)Statistics
----------------------------------------------------------1  recursive calls0  db block gets392  consistent gets0  physical reads0  redo size726  bytes sent via SQL*Net to client523  bytes received via SQL*Net from client2  SQL*Net roundtrips to/from client0  sorts (memory)0  sorts (disk)2  rows processed
--mysql,可以走索引
explain select * from t_mysql where name is null;
或者
explain select * from t_mysql where name <=> null;
+----+-------------+---------+------------+------+---------------+-------+---------+-------+------+----------+-----------------------+
| id | select_type | table   | partitions | type | possible_keys | key   | key_len | ref   | rows | filtered | Extra                 |
+----+-------------+---------+------------+------+---------------+-------+---------+-------+------+----------+-----------------------+
|  1 | SIMPLE      | t_mysql | NULL       | ref  | idx_1         | idx_1 | 43      | const |    2 |   100.00 | Using index condition |
+----+-------------+---------+------------+------+---------------+-------+---------+-------+------+----------+-----------------------+
1 row in set, 1 warning (0.00 sec)
--tidb,可以走索引
13:40:28[5.7.25-TiDB-v3.0.17]root->192.168.30.11[mtest]> explain select * from t_tidb where name is null;
+-------------------+-------+------+-----------------------------------------------------------------------------+
| id                | count | task | operator info                                                               |
+-------------------+-------+------+-----------------------------------------------------------------------------+
| IndexLookUp_10    | 10.00 | root |                                                                             |
| ├─IndexScan_8     | 10.00 | cop  | table:t_tidb, index:name, range:[NULL,NULL], keep order:false, stats:pseudo |
| └─TableScan_9     | 10.00 | cop  | table:t_tidb, keep order:false, stats:pseudo                                |
+-------------------+-------+------+-----------------------------------------------------------------------------+
3 rows in set (0.00 sec)--但是<=>这种写法,tidb中执行计划走的是全表扫描,与优化器的逻辑处理有关
13:52:41[5.7.25-TiDB-v3.0.17]root->192.168.30.11[mtest]> explain select * from t_tidb where name <=> null;
+---------------------+----------+------+-----------------------------------------------------------------+
| id                  | count    | task | operator info                                                   |
+---------------------+----------+------+-----------------------------------------------------------------+
| TableReader_7       | 8000.00  | root | data:Selection_6                                                |
| └─Selection_6       | 8000.00  | cop  | nulleq(mtest.t_tidb.name, NULL)                                 |
|   └─TableScan_5     | 10000.00 | cop  | table:t_tidb, range:[-inf,+inf], keep order:false, stats:pseudo |
+---------------------+----------+------+-----------------------------------------------------------------+
3 rows in set (0.00 sec)

mysql5.7中对<=>操作符的解释:

<=>NULL-safe equal. This operator performs an equality comparison like the = operator, but returns 1 rather than NULL if both operands are NULL, and 0 rather than NULL if one operand is NULL.The <=> operator is equivalent to the standard SQL IS NOT DISTINCT FROM operator.mysql> SELECT 1 <=> 1, NULL <=> NULL, 1 <=> NULL;-> 1, 1, 0
mysql> SELECT 1 = 1, NULL = NULL, 1 = NULL;-> 1, NULL, NULL
For row comparisons, (a, b) <=> (x, y) is equivalent to:(a <=> x) AND (b <=> y)

按照sql标准定义,空值肯定不等于空值,但mysql为了某种方便,使用<=>可以比较两个null值是否相等。

小结:对于null值的筛选请使用is null和is not null

总结:Oracle中name is null不会走索引,oracle数据库的普通索引结构中不会存储Null值。

mysql中的null值可以走索引,简单来讲InnoDB中规定NULL值必须用整数个字节的位表示,如果使用的二进制位个数不是整数个字节,则在字节的高位补0,代表该值为null。

Mysql Oracle Tidb对空值的处理相关推荐

  1. MySQL,Oracle系统学习,以及SQL语言-----数据库篇学习笔记

    Handouts MySQL和Oracle系统学习 一. 开篇立意(~~~~必看,有说明~~~~) 二. Oracle 篇 数据库存在之意义 基础概念(必须看,后面不会说明!!!) Oracle管理系 ...

  2. oracle增量 mysql_是否有任何mysql / Oracle函数给予增量号。基于另一列相似值的一列?...

    我有兴趣知道是否有任何MySQL / Oracle函数给增量号.在另一列相似的值的基础上的一列? 就像在我的下面的代码中,我有order_primary列,其中包含订单号.所以基于此我们可以确定有多少 ...

  3. 通过Sqoop实现Mysql / Oracle 与HDFS / Hbase互导数据

    通过Sqoop实现Mysql / Oracle 与HDFS / Hbase互导数据\ 下文将重点说明通过Sqoop实现Mysql与HDFS互导数据,Mysql与Hbase,Oracle与Hbase的互 ...

  4. Python中操作MySQL/Oracle

    Python中操作MySQL/Oracle 一.Python操作数据库介绍 二.Python操作MySQL 2.1 PySQL模块 2.1.1 安装PyMySQL 2.2 基本使用 2.3 获取最新创 ...

  5. SQLErrorCodes loaded: [DB2, Derby, H2, HSQL, Informix, MS-SQL, MySQL, Oracle, PostgreSQL, Sybase, Ha

    前言 mysql 5.7 ssm 前两天遇到了这个异常,记录一下: [INFO][2019-10-06 02:03:39,268][org.springframework.beans.factory. ...

  6. MYSQL,Oracle,SQL数据库在JSP中的驱动

    MYSQL,Oracle,SQL数据库在JSP中的驱动 datasource.url=jdbc:mysql://localhost:3306/bbscs6?useUnicode=true&ch ...

  7. 手机版数据库oracle,用手机管理及维护MySQL,Oracle等数据库

    sql server 导出的datetime结果 CAST(0x00009E0E0095524F AS DateTime) 如何向mysql,oracle等数据库进行转换 1. 处理 sql serv ...

  8. mysql中ak替换键_数据库:唯一性约束_alternate key(替换键) mySQL Oracle 数据库 ak 唯一性约束...

    数据库:唯一性约束_alternate key(替换键) mySQL Oracle 数据库 ak 唯一性约束 数据库:唯一性约束 所谓唯一性约束(unique constraint)不过是数据表内替代 ...

  9. Atitit. 数据约束 校验 原理理论与 架构设计 理念模式java php c#.net js javascript mysql oracle...

    Atitit. 数据约束 校验 原理理论与 架构设计 理念模式java php c#.net js javascript mysql oracle 1. 主键1 2. uniq  index2 3.  ...

最新文章

  1. arcsde安装步骤_ArcGIS 9.3 安装之 SDE的安装及使用
  2. 【RAC】使用一条“ps”命令获取Linux环境下全部RAC集群进程信息
  3. GIS开发随笔(3)——ArcXML和NET_Link方法
  4. Dubbo入门(一)
  5. linux环境下安装PHP中间件ICE(二)
  6. 导出jar插件_Fluttify输出的Flutter插件工程详解
  7. linux退出windows域,删除Windows AD域控制器的三种方法
  8. bootstrap搜索框_Bootstrap 开源 SVG 图标库 Bootstrap Icons
  9. python手动绘图案例_python绘图案例——递归绘制分形树
  10. Nginx源码分析 - 基础数据结构篇 - 双向链表结构 ngx_queue.c(05)
  11. mysql动态代理_动态代理连接数据库
  12. 驱动精灵万能网卡版单文件版 v9.61
  13. 在计算机领域黑箱,计算机模拟电学黑箱
  14. 我在名牌大学毕业后的经历
  15. 【Unity问题】Int类型除法运算为什么归零
  16. ADM pro破解百度云限速 ADM pro设置方法 ES文件管理器
  17. 在虚拟机中开启VT功能
  18. Skype for Business Server 2015-07-边缘服务器-1-安装-先决条件
  19. python 正态分布图_用python制作正态分布图
  20. RocketMQ消费失败重试机制分析

热门文章

  1. 比特币系列——竞争币、竞争块链和应⽤程序
  2. 浙大 PAT b1023
  3. 百度提前批算法工程师面筋!效率有、高
  4. 【论文】Awesome Relation Classification Paper(关系分类)(PART II)
  5. python识别简单训练模型_Python-OpenCV —— 物体识别(TrainCascadeClassification)
  6. 如何快速搭建自己的独立站?
  7. java io操作压缩文件_Java操作zip-压缩和解压文件
  8. java I O类大全_Java I/O —— File类
  9. 查看 php yii脚本位置,Yii框架分析(一)入口脚本index.php的启动过程剖析
  10. linux系统在windows看不到,Linux下怎么看不到盘符啊?