mysql c null_MySQL中NULL字段的比较问题
最近有人问我MySQL中一个字段不论=NULL还是<>NULL都匹配不了数据,是在框架层实现的还是在存储引擎层实现的,我说你看看如果InnoDB表和MyISAM表都有这个现象,那就比较可能是在框架层。
当然这个答案跟没有回答一样,我们可以从代码上看看具体的实现部分。
1、现象描述
表结构
CREATE TABLE `t` (
`c` char(32) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=gbk
插入两行数据
insert into t (c) values('a'),(null);
查询
mysql> select * from t where c=null;
Empty set (0.00 sec)
mysql> select * from t where c<>null;
Empty set (0.00 sec)
mysql> select * from t where c is not null;
+------+
| c|
+------+
| a|
+------+
1 row in set (0.00 sec)
说明:从上面的三个查询可以看出,使用=null和<>null都无法返回数据,只能通过is或is not来比较。
2、代码相关
我们知道大概的流程,是引擎返回索引过滤后的结果,在框架层再依次判断记录是否符合条件。判断条件是否满足是在函数evaluate_join_record (sql_select.cc)中。
if (select_cond)
{
select_cond_result= test(select_cond->val_int()); /* check for errors evaluating the condition */
if (join->thd->is_error())
return NESTED_LOOP_ERROR;
}
if (!select_cond || select_cond_result)
{ ... }
第三行的select_cond->val_int(),就是判断where的条件是否相同。其中select_cond的类型Item是一个虚类。我们从val_int()的函数注释中看到这样一句话“In case of NULL value return 0 and set null_value flag to TRUE.”,确认了这个是在框架层作的,而且是有意为之。
一路追查到这个函数int Arg_comparator::compare_string (sql/item_cmpfunc.cc),这个函数是用语判断两个字符串是否相同。
int Arg_comparator::compare_string()
{
String *res1,*res2;
if ((res1= (*a)->val_str(&value1)))
{
if ((res2= (*b)->val_str(&value2)))
{
if (set_null)
owner->nullvalue= 0;
return sortcmp(res1,res2,cmp_collation.collation);
}
}
if (set_null)
owner->nullvalue= 1;
return -1;
}
函数返回值为0时表示相同,否则不同。
其中a是左值,b是右值。即如果输入的是where ‘i’=c,则a的值是’i’。从第4行和第6行的两个if看到,当a和b中有一个是null的时候,不进入sortcmp,而是直接return -1。
3、验证修改
声明:这个只是为了验证结论修改,纯属练手,实际上现有的策略并没有问题。
int Arg_comparator::compare_string()
{
String *res1,*res2;
res1= (*a)->val_str(&value1);
res2= (*b)->val_str(&value1);
if (!res1 && !res2)
{
return 0;
}
else if ((!res1 && res2) || (res1 && !res2))
{
return 1;
}
else
{
return sortcmp(res1,res2,cmp_collation.collation);
}
}
重新编译后执行效果如下
mysql> select * from t where c=null;
+--------------+
| c|
+--------------+
| NULL |
+--------------+
1 row in set (0.00 sec)
mysql> select * from t where c<>null;
+--------------+
| c|
+--------------+
| a|
+--------------+
1 row in set (0.00 sec)
记得改回去。。。 ^_^
4、相关说明
a)Arg_comparator::compare_string()这个函数只用于定义两个char[]的判断规则,因此修改后的执行程序中,非字符串字段判断仍为原来的规则,即=null和<>null都认为不匹配。
b)标准判断是否为null的用法是where c is null和is not null。此时使用的判断函数为Item_func_isnull::val_int()和Item_func_isnotnull::val_int(),这两个函数比较简单,直接用args[0]->is_null()判断。
2
顶
0
踩
分享到:
2010-12-06 21:21
浏览 10953
分类:数据库
评论
mysql c null_MySQL中NULL字段的比较问题相关推荐
- 如何更新mysql数据库字段_如何使用MySQL一个表中的字段更新另一个表中字段
1,修改1列 update student s, city c set s.city_name = c.name where s.city_code = c.code; 2,修改多个列 update ...
- mysql高效查出重复的手机号_Mysql必读MySQL大表中重复字段的高效率查询方法
<MysqL必读MysqL大表中重复字段的高效率查询方法>要点: 本文介绍了MysqL必读MysqL大表中重复字段的高效率查询方法,希望对您有用.如果有疑问,可以联系我们.MysqL大表重 ...
- mysql修改表中某个字段的默认值
Mysql中用SQL增加.删除字段,修改字段名.字段类型.注释,调整字段顺序总结 在网站重构中,通常会进行数据结构的修改,所以添加,删除,增加mysql表的字段是难免的,有时为了方便,还会增加修改表或 ...
- mysql:分组中某字段最大值的查询结果
最近在用一款组态软件,涉及到sql查询来得出数据集.需要在一定的限制下,得出想要的查询结果.某些查询的方法整理一下. 这次记录的是分组中某字段最大值的查询结果: 比如:从一张记录装置缺陷的表中,查询出 ...
- mysql的字段空格是null_MySQL中NULL与空字符串 空格问题
一些刚刚接触MySQL的孩子,经常会错误的认为NULL与空字符串' '是相同的.这看似是一件不重要的事情,但是在MySQL中,这两者是完全不同的.NULL是指没有值,而''则表示值是存在的,只不过是个 ...
- mysql联合索引排序_对mysql联合索引中的字段进行合理排序
在MySQL的where条件中,有时会用到很多的条件,通常为了加快速度会把这些字段放到联合索引中,可以更快的提高搜索速度: 但是对联合索引中字段顺序的合理排序,便更能提高速度 例子:select * ...
- mysql取最大一条数据,mysql取出表中,某字段值最大的一条纪录,sql语句
一个为交易表,有唯一id,别名trade_id 一个为交易状态详情表,记录trade_id的多个状态. 进行了两个表查询.查询某个trade_id的交易情况及最新状态. 直接粘贴此sql,执行即知. ...
- mysql查询数据库中所有字段的属性
大型项目中数据库中有成百上千张表,想要统计数据库中相同的字段名,不同的长度或类型,所有的字段属性. 利用简单的SQL帮助我们进行统计. 1.查询数据库中某个库所有字段的属性(指定数据库库名),若想查询 ...
- mysql如何查询表中所有字段的名字
select COLUMN_NAME,column_comment from INFORMATION_SCHEMA.Columns where table_name='表名' and table_sc ...
最新文章
- Matlab使用笔记
- 利用fnd_conc_global.set_req_globals设置子请求的Parent Request ID
- C#集合类(HashTable, Dictionary, ArrayList)与HashTable线程安全
- LeetCode打卡 52八皇后Ⅱ53最大子序和54螺旋矩阵
- Hardcoded string , should use @string resource警告 Tag start is not closed
- 哈利波特检索_语料库ing说: 难怪哈利波特与混血王子那么好看
- 非苹果PC安装MacOS
- C# 日志管理框架:Common.Logging和log4net
- 支付宝的一些小问题,注意事项等等,等用得时候在来写写
- C++ | Qt 获取局域网中存在的主机(IP以及主机名)
- android 圆点指示器,ViewPager加上小圆点指示器效果
- java sun包无法引用_关于java包的问题,自己创建一个包,里面放了源文件,却包外无法引用:具体见问题补充...
- ubuntu linux 从入门到精通.pdf,UBUNTU LINUX从入门到精通(附DVD)
- 微信公众号服务号如何在线给粉丝发送模板消息
- C语言求解黎曼 函数非平凡零点,51、黎曼函数的“非平凡零点 (1/2)z”是什么玩意?...
- 你听过“易语言”吗?
- 常见的厂家的加固方式做一下总结
- 使用Anki批量导入选择题实录
- 一文搞定:SpringBoot、SLF4j、Log4j、Logback、Netty之间混乱关系(史上最全)
- vue学习笔记(一)
热门文章
- IDEA导入项目笔记二
- python把csv做成柱状图_用Python的Matplotlib模块实现CSV数据格式的可视化
- oracle升级后报 06502,Oracle数据库升级后报ORA-00704和ORA-39700错误
- JS(ES6)、Vue.js、node.js
- 调试 Dockerfile - 每天5分钟玩转 Docker 容器技术(15)
- 细说IIS异常日志 — 你必须知道的功能
- Linux软件间的依赖关系(转)
- Mysql笔记之 -- replace()实现mysql 替换字符串
- POST方式提交乱码解决
- Android 音频均衡器,可通过拖动调节音频EQ