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 运行环境建议规范 挂载点 大小 分区类型 分区 ...
随机推荐
- Castle.DynamicProxy的使用
.Net平台AOP技术研究 简单实现 通过继承实现 public interface ICoding { void DoSth(); } public class Coding : ICoding { ...
- java代码混淆
仅做记录之用. java代码可以反编译,因此有时候要保护自己的知识产权还真得费点心思,一般来说有三个思路: 1.将class文件加密,这个是最安全的,但也费事儿,因为要重写classloader来解密 ...
- HDU 5587——Array——————【规律】
Array Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)Total Sub ...
- 如何结合后台数据库 启动vue项目
一:连接数据库 1. 点击打开后输入密码 2.查看数据库 show databases; 3.创建数据库 create database jd; 删除数据库 drop database jd; 4.使 ...
- C#实现Ping服务器
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...
- golang中并发的相关知识
golang中done channel理解:https://segmentfault.com/a/1190000006261218 golang并发模型之使用Context:https://segme ...
- linux创建用户与删除用户及问题解决(ubuntu)
创建的用户不正确,一直在删除创建,发现了挺多问题也学到了一些东西如下是我的总结. (root用户设置: 由于ubtun系统默认是没有激活root用户的,需要我们手工进行操作,在命令行界面下,或者在终端 ...
- UITableView分隔线
问题1: 在ios中使用UITableView时,当行数较少是,可能一屏幕能显示完全所有行,这时候会出现下面的问题,显示多余的分隔线 图如下: 解决方案: //解决方案1 //添加如下代码 -(CGF ...
- css多行文本溢出显示省略号
HTML: <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <met ...
- [转c#]记录程序耗时的方法
多时候需要输出程序耗时,然后记录下来, 总是在程序执行开始记录当前时间点,在结尾记录结束时间点,然后两个时间相减, 那么有没有其他稍微像样点的方法呢? 告诉你,有滴 ; ) 这个方法主体就是 ...