MySQL为何不建议使用null列
(root@localhost mysql3306.sock)[zlm]>create table test_null(
-> id int not null,
-> name varchar()
-> );
Query OK, rows affected (0.02 sec) (root@localhost mysql3306.sock)[zlm]>insert into test_null values(,'zlm');
Query OK, row affected (0.00 sec) (root@localhost mysql3306.sock)[zlm]>insert into test_null values(,null);
Query OK, row affected (0.00 sec) (root@localhost mysql3306.sock)[zlm]>select * from test_null;
+----+------+
| id | name |
+----+------+
| | zlm |
| | NULL |
+----+------+
rows in set (0.00 sec) (root@localhost mysql3306.sock)[zlm]>select * from test_null where name=null;
Empty set (0.00 sec) (root@localhost mysql3306.sock)[zlm]>select * from test_null where name is null;
+----+------+
| id | name |
+----+------+
| | NULL |
+----+------+
row in set (0.00 sec) (root@localhost mysql3306.sock)[zlm]>select * from test_null where name is not null;
+----+------+
| id | name |
+----+------+
| | zlm |
+----+------+
row in set (0.00 sec) (root@localhost mysql3306.sock)[zlm]>select * from test_null where null=null;
Empty set (0.00 sec) (root@localhost mysql3306.sock)[zlm]>select * from test_null where null<>null;
Empty set (0.00 sec) (root@localhost mysql3306.sock)[zlm]>select * from test_null where null<=>null;
+----+------+
| id | name |
+----+------+
| | zlm |
| | NULL |
+----+------+
rows in set (0.00 sec) //null<=>null always return true,it's equal to "where 1=1".
(root@localhost mysql3306.sock)[zlm]>SELECT IS NULL, IS NOT NULL, '' IS NULL, '' IS NOT NULL;
+-----------+---------------+------------+----------------+
| IS NULL | IS NOT NULL | '' IS NULL | '' IS NOT NULL |
+-----------+---------------+------------+----------------+
| | | | |
+-----------+---------------+------------+----------------+
row in set (0.00 sec) //It's not equal to zero number or vacant string.
//In MySQL,0 means fasle,1 means true. (root@localhost mysql3306.sock)[zlm]>SELECT = NULL, <> NULL, < NULL, > NULL;
+----------+-----------+----------+----------+
| = NULL | <> NULL | < NULL | > NULL |
+----------+-----------+----------+----------+
| NULL | NULL | NULL | NULL |
+----------+-----------+----------+----------+
row in set (0.00 sec) //It cannot be compared with number.
//In MySQL,null means false,too.
(root@localhost mysql3306.sock)[zlm]>select ifnull(null,'First is null'),ifnull(null+,'First is null'),ifnull(concat('abc',null),'First is null');
+------------------------------+---------------------------------+--------------------------------------------+
| ifnull(null,'First is null') | ifnull(null+,'First is null') | ifnull(concat('abc',null),'First is null') |
+------------------------------+---------------------------------+--------------------------------------------+
| First is null | First is null | First is null |
+------------------------------+---------------------------------+--------------------------------------------+
row in set (0.00 sec)
//null value needs to be disposed with ifnull() function,what usually causes sql statement more complex.
//As we all know,MySQL does not support funcion index.Therefore,indexes on the column may not be used.That's really worse.
(root@localhost mysql3306.sock)[zlm]>select count(*),count(name) from test_null;
+----------+-------------+
| count(*) | count(name) |
+----------+-------------+
| | |
+----------+-------------+
row in set (0.00 sec) //count(*) returns all rows ignore the null while count(name) returns the non-null rows in column "name".
//This will also leads to uncertainty if someone is unaware of the details above.
(root@localhost mysql3306.sock)[zlm]>insert into test_null values(,null);
Query OK, row affected (0.00 sec) (root@localhost mysql3306.sock)[zlm]>select distinct name from test_null;
+------+
| name |
+------+
| zlm |
| NULL |
+------+
rows in set (0.00 sec) //Two rows of null value returned one and the result became two. (root@localhost mysql3306.sock)[zlm]>select name from test_null group by name;
+------+
| name |
+------+
| NULL |
| zlm |
+------+
rows in set (0.00 sec) //Two rows of null value were put into the same group.
//By default,group by will also sort the result(null row showed first). (root@localhost mysql3306.sock)[zlm]>select id,name from test_null order by name;
+----+------+
| id | name |
+----+------+
| | NULL |
| | NULL |
| | zlm |
+----+------+
rows in set (0.00 sec) //Three rows were sorted(two null rows showed first).
(root@localhost mysql3306.sock)[sysbench]>show tables;
+--------------------+
| Tables_in_sysbench |
+--------------------+
| sbtest1 |
| sbtest10 |
| sbtest2 |
| sbtest3 |
| sbtest4 |
| sbtest5 |
| sbtest6 |
| sbtest7 |
| sbtest8 |
| sbtest9 |
+--------------------+
rows in set (0.00 sec) (root@localhost mysql3306.sock)[sysbench]>show create table sbtest1\G
*************************** . row ***************************
Table: sbtest1
Create Table: CREATE TABLE `sbtest1` (
`id` int() NOT NULL AUTO_INCREMENT,
`k` int() NOT NULL DEFAULT '',
`c` char() NOT NULL DEFAULT '',
`pad` char() NOT NULL DEFAULT '',
PRIMARY KEY (`id`),
KEY `k_1` (`k`)
) ENGINE=InnoDB AUTO_INCREMENT= DEFAULT CHARSET=utf8
row in set (0.00 sec) (root@localhost mysql3306.sock)[sysbench]>alter table sbtest1 modify k int null,modify c char() null,modify pad char() null;
Query OK, rows affected (4.14 sec)
Records: Duplicates: Warnings: (root@localhost mysql3306.sock)[sysbench]>insert into sbtest1 values(,null,null,null);
Query OK, row affected (0.00 sec) (root@localhost mysql3306.sock)[sysbench]>explain select id,k from sbtest1 where id=;
+----+-------------+---------+------------+-------+---------------+---------+---------+-------+------+----------+-------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+---------+------------+-------+---------------+---------+---------+-------+------+----------+-------+
| | SIMPLE | sbtest1 | NULL | const | PRIMARY | PRIMARY | | const | | 100.00 | NULL |
+----+-------------+---------+------------+-------+---------------+---------+---------+-------+------+----------+-------+
row in set, warning (0.00 sec) (root@localhost mysql3306.sock)[sysbench]>explain select id,k from sbtest1 where k is null;
+----+-------------+---------+------------+------+---------------+------+---------+-------+------+----------+--------------------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+---------+------------+------+---------------+------+---------+-------+------+----------+--------------------------+
| | SIMPLE | sbtest1 | NULL | ref | k_1 | k_1 | | const | | 100.00 | Using where; Using index |
+----+-------------+---------+------------+------+---------------+------+---------+-------+------+----------+--------------------------+
row in set, warning (0.00 sec) //In the first query,the newly added row is retrieved by primary key.
//In the second query,the newly added row is retrieved by secondary key "k_1"
//It has been proved that indexes can be used on the columns which contain null value.
//column "k" is int datatype which occupies 4 bytes,but the value of "key_len" turn out to be 5.what's happed?Because null value needs 1 byte to store the null flag in the rows.
- null value always leads to many uncertainties when disposing sql statement.It may cause bad performance accidentally.
- null value will not be estimated in aggregate function(eg. count(),max(),min()) which may cause inaccurate results.
- null value will influence the behavior of the operations such as "distinct","group by","order by" which causes wrong sort.
- null value needs ifnull() function to do judgement which makes the program code more complex.
- null value needs a extra 1 byte to store the null information in the rows.
- As these above drawbacks,it's not recommended to define columns with default null.
- We recommand to define "not null" on all columns and use zero number & vacant string to substitute relevant data type of null.
MySQL为何不建议使用null列的更多相关文章
- 50多条mysql数据库优化建议
1.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引. 缺省情况下建立的索引是非群集索引,但有时它并不是最佳的.在非群集索引下,数据在物理上随机存 ...
- MySQL优化小建议
背景 "那啥,你过来一下!" "怎么了?我代码都单元测试了的,没出问题啊!"我一脸懵逼跑到运维大佬旁边. "你看看!你看看!多少条报警,赶快优化一下! ...
- MySQL高性能优化规范建议,速度收藏
数据库命令规范 •所有数据库对象名称必须使用小写字母并用下划线分割•所有数据库对象名称禁止使用 MySQL 保留关键字(如果表名中包含关键字查询时,需要将其用单引号括起来)•数据库对象的命名要能做到见 ...
- (1) Mysql高性能优化规范建议
数据库命令规范 所有数据库对象名称必须使用小写字母并用下划线分割 所有数据库对象名称禁止使用mysql保留关键字(如果表名中包含关键字查询时,需要将其用单引号括起来) 数据库对象的命名要能做到见名识意 ...
- WebAPI调用笔记 ASP.NET CORE 学习之自定义异常处理 MySQL数据库查询优化建议 .NET操作XML文件之泛型集合的序列化与反序列化 Asp.Net Core 轻松学-多线程之Task快速上手 Asp.Net Core 轻松学-多线程之Task(补充)
WebAPI调用笔记 前言 即时通信项目中初次调用OA接口遇到了一些问题,因为本人从业后几乎一直做CS端项目,一个简单的WebAPI调用居然浪费了不少时间,特此记录. 接口描述 首先说明一下,基于 ...
- Mysql高性能优化规范建议
数据库命令规范 所有数据库对象名称必须使用小写字母并用下划线分割 所有数据库对象名称禁止使用mysql保留关键字(如果表名中包含关键字查询时,需要将其用单引号括起来) 数据库对象的命名要能做到见名识意 ...
- 从原理上理解MySQL的优化建议
从原理上理解MySQL的优化建议 预备知识 B+树索引 mysql的默认存储引擎InnoDB使用B+树来存储数据的,所以在分析优化建议之前,了解一下B+树索引的基本原理. 上图是一个B+树索引示意图, ...
- MySQL 高性能优化规范建议
数据库命令规范 所有数据库对象名称必须使用小写字母并用下划线分割 所有数据库对象名称禁止使用 MySQL 保留关键字(如果表名中包含关键字查询时,需要将其用单引号括起来) 数据库对象的命名要能做到见名 ...
- MySQL 运行环境建议规范
一.操作系统环境 操作系统版本选择 CentOS/RHRL/ORACLE Linux 5.x/6.x x86_64 发行版 建议磁盘分区规则 MySQL 运行环境建议规范 挂载点 大小 分区类型 分区 ...
随机推荐
- Quartz使用(5) - Quartz的Job存储及集群部署
1. Job的存储与持久化 Quartz的JobStore接口定义了作业Job.触发器trigger.调度器Scheduler等数据存储机制.Quartz主要有两种Job存储类型:内存存储RAMJob ...
- C面向对象编程
C语言面向对象编程 1. 定义一个SuperObject结构体, 里面包含最少的元素, 但是确实每一个对象都含有的, 这样可以实现多态 2. 每一个对象都是基于类的, 我们知道类都是单例对象, 所以我 ...
- Python 爬虫实战(二):使用 requests-html
Python 爬虫实战(一):使用 requests 和 BeautifulSoup,我们使用了 requests 做网络请求,拿到网页数据再用 BeautifulSoup 解析,就在前不久,requ ...
- Struts2_结果类型_resulttype_1
看下面的例子: 一般使用4种:dispatcher(容器内跳转到JSP页面).redirect(重定向到jsp页面).chain(容器内跳转到另一个Action).redirectAction(重定向 ...
- Limesurvey-2.55 (Ubuntu 16.04)
平台: Ubuntu 类型: 虚拟机镜像 软件包: limesurvey-2.55 business intelligence commercial limesurvey open-source 服务 ...
- 在Sql Server中使用Guid类型的列及设置Guid类型的默认值
1.列的类型为uniqueidentifier 2.列的默认值可以设为newid()
- [转]Android中Spinner下拉列表(使用ArrayAdapter和自定义Adapter实现)
今天学习了Spinner组件,使用Spinner相当于从下拉列表中选择项目,下面演示一下Spinner的使用(分别使用ArrayAdapter和自定义Adapter实现) (一):使用ArrayAda ...
- CentOS6下DHCP服务(二)简单配置案例及故障排查
1.预分配网络参数如下:linux服务器:eth0 IP为192.168.8.250 做为局域网DHCP服务器局域网网段设置为192.168.8.0/24:内部计算机的router为192.168. ...
- navicat for mysql注册码:NAVN-LNXG-XHHX-5NOO
名.组织可以为空或任意填写. 摘自: navicat for mysql10.0.0.0注册码中“名”.“组织”...._百度知道
- String Painter, Chengdu 2008, LA4394
题目链接:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_ ...