Mysql Oracle Tidb对空值的处理
三种类型的数据库下面分别创建对应的测试表:
--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对空值的处理相关推荐
- MySQL,Oracle系统学习,以及SQL语言-----数据库篇学习笔记
Handouts MySQL和Oracle系统学习 一. 开篇立意(~~~~必看,有说明~~~~) 二. Oracle 篇 数据库存在之意义 基础概念(必须看,后面不会说明!!!) Oracle管理系 ...
- oracle增量 mysql_是否有任何mysql / Oracle函数给予增量号。基于另一列相似值的一列?...
我有兴趣知道是否有任何MySQL / Oracle函数给增量号.在另一列相似的值的基础上的一列? 就像在我的下面的代码中,我有order_primary列,其中包含订单号.所以基于此我们可以确定有多少 ...
- 通过Sqoop实现Mysql / Oracle 与HDFS / Hbase互导数据
通过Sqoop实现Mysql / Oracle 与HDFS / Hbase互导数据\ 下文将重点说明通过Sqoop实现Mysql与HDFS互导数据,Mysql与Hbase,Oracle与Hbase的互 ...
- Python中操作MySQL/Oracle
Python中操作MySQL/Oracle 一.Python操作数据库介绍 二.Python操作MySQL 2.1 PySQL模块 2.1.1 安装PyMySQL 2.2 基本使用 2.3 获取最新创 ...
- 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. ...
- MYSQL,Oracle,SQL数据库在JSP中的驱动
MYSQL,Oracle,SQL数据库在JSP中的驱动 datasource.url=jdbc:mysql://localhost:3306/bbscs6?useUnicode=true&ch ...
- 手机版数据库oracle,用手机管理及维护MySQL,Oracle等数据库
sql server 导出的datetime结果 CAST(0x00009E0E0095524F AS DateTime) 如何向mysql,oracle等数据库进行转换 1. 处理 sql serv ...
- mysql中ak替换键_数据库:唯一性约束_alternate key(替换键) mySQL Oracle 数据库 ak 唯一性约束...
数据库:唯一性约束_alternate key(替换键) mySQL Oracle 数据库 ak 唯一性约束 数据库:唯一性约束 所谓唯一性约束(unique constraint)不过是数据表内替代 ...
- Atitit. 数据约束 校验 原理理论与 架构设计 理念模式java php c#.net js javascript mysql oracle...
Atitit. 数据约束 校验 原理理论与 架构设计 理念模式java php c#.net js javascript mysql oracle 1. 主键1 2. uniq index2 3. ...
最新文章
- arcsde安装步骤_ArcGIS 9.3 安装之 SDE的安装及使用
- 【RAC】使用一条“ps”命令获取Linux环境下全部RAC集群进程信息
- GIS开发随笔(3)——ArcXML和NET_Link方法
- Dubbo入门(一)
- linux环境下安装PHP中间件ICE(二)
- 导出jar插件_Fluttify输出的Flutter插件工程详解
- linux退出windows域,删除Windows AD域控制器的三种方法
- bootstrap搜索框_Bootstrap 开源 SVG 图标库 Bootstrap Icons
- python手动绘图案例_python绘图案例——递归绘制分形树
- Nginx源码分析 - 基础数据结构篇 - 双向链表结构 ngx_queue.c(05)
- mysql动态代理_动态代理连接数据库
- 驱动精灵万能网卡版单文件版 v9.61
- 在计算机领域黑箱,计算机模拟电学黑箱
- 我在名牌大学毕业后的经历
- 【Unity问题】Int类型除法运算为什么归零
- ADM pro破解百度云限速 ADM pro设置方法 ES文件管理器
- 在虚拟机中开启VT功能
- Skype for Business Server 2015-07-边缘服务器-1-安装-先决条件
- python 正态分布图_用python制作正态分布图
- RocketMQ消费失败重试机制分析
热门文章
- 比特币系列——竞争币、竞争块链和应⽤程序
- 浙大 PAT b1023
- 百度提前批算法工程师面筋!效率有、高
- 【论文】Awesome Relation Classification Paper(关系分类)(PART II)
- python识别简单训练模型_Python-OpenCV —— 物体识别(TrainCascadeClassification)
- 如何快速搭建自己的独立站?
- java io操作压缩文件_Java操作zip-压缩和解压文件
- java I O类大全_Java I/O —— File类
- 查看 php yii脚本位置,Yii框架分析(一)入口脚本index.php的启动过程剖析
- linux系统在windows看不到,Linux下怎么看不到盘符啊?