mysql 查询空字符串 设置默认值_MySQL默认值选型是空,还是 NULL-爱可生

29b4c9f774788a19d167f6adf9dc7b09.png

如果对一个字段没有过多要求,是使用“”还是使用 NULL,一直是个让人困惑的问题。即使有前人留下的开发规范,但是能说清原因的也没有几个。NULL 是“”吗?在辨别 NULL 是不是空的这个问题上,感觉就像是在证明 1 + 1 是不是等于 2。

在 MySQL 中的 NULL 是一种特殊的数据。一个字段是否允许为 NULL,字段默认值是否为 NULL。

主要有如下几种情况:

字段类型表定义中设置方式字段值数值类型 (INT/BIGINT)Default NULL / Default 0NULL / NUM字符类型 (CHAR/VARCHAR)Default NULL / Default '' / Default 'ab'NULL / '' / String

1. NULL 与空字符存储上的区别

表中如果允许字段为 NULL,会为每行记录分配 NULL 标志位。NULL 除了在每行的行首存有 NULL 标志位,实际存储不占有任何空间。如果表中所有字段都是非 NULL,就不存在这个标示位了。网上有一些验证 MySQL 中 NULL 存储方式的文章,可以参考下。

2. NULL使用上的一些问题。

数值类型,对一个允许为NULL的字段进行min、max、sum、加减、order by、group by、distinct 等操作的时候。字段值为非 NULL 值时,操作很明确。如果使用 NULL, 需要清楚的知道如下规则:

数值类型,以 INT 列为例

1) 在 min / max / sum / avg 中 NULL 值会被直接忽略掉,如下是测试结果,可能 min / max / sum 还比较可以理解,但 avg 真的是你想要的结果吗?

    CREATE TABLE `t1` (    `id` int(16) NOT NULL AUTO_INCREMENT,    `name` varchar(20) DEFAULT NULL,    `number` int(11) DEFAULT NULL,    PRIMARY KEY (`id`)    ) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;    select * from t1;    +------+----------+--------+    | id   | name     | number |    +------+----------+--------+    |    1 | zhangsan |   NULL |    |    2 | lisi     |   NULL |    |    3 | wangwu   |      0 |    |    4 | zhangliu |      4 |    +------+----------+--------+    select max(number) from t1;    +-------------+    | max(number) |    +-------------+    |           4 |    +-------------+    select min(number) from t1;    +-------------+    | min(number) |    +-------------+    |           0 |    +-------------+    select sum(number) from t1;    +-------------+    | sum(number) |    +-------------+    |           4 |    +-------------+    select avg(number) from t1;    +-------------+    | avg(number) |    +-------------+    |      2.0000 |    +-------------+

2) 对 NULL 做加减操作,如 1 + NULL,结果仍是 NULL

    select 1+NULL;    +--------+    | 1+NULL |    +--------+    |   NULL |    +--------+

3) order by 以升序检索字段的时候 NULL 会排在最前面(倒序相反)

    select * from t1 order by number;    +----+----------+--------+    | id | name     | number |    +----+----------+--------+    |  1 | zhangsan |   NULL |    |  2 | lisi     |   NULL |    |  3 | wangwu   |      0 |    |  4 | zhangliu |      4 |    +----+----------+--------+    select * from t1 order by number desc;    +----+----------+--------+    | id | name     | number |    +----+----------+--------+    |  4 | zhangliu |      4 |    |  3 | wangwu   |      0 |    |  1 | zhangsan |   NULL |    |  2 | lisi     |   NULL |    +----+----------+--------+

4) group by / distinct 时,NULL 值被视为相同的值

    select distinct(number) from t1;    +--------+    | number |    +--------+    |   NULL |    |      0 |    |      4 |    +--------+    select number,count(*) from t1 group by number;    +--------+----------+    | number | count(*) |    +--------+----------+    |   NULL |        2 |    |      0 |        1 |    |      4 |        1 |    +--------+----------+

字符类型,在使用 NULL 值的时候,也需要格外注意

1) 字段是字符时,你无法一目了然的区分这个值到底是 NULL ,还是字符串 'NULL'

    insert into t1 (name,number) values ('NULL',5);    insert into t1 (number) values (6);    select * from t1 where number in (5,6);    +----+------+--------+    | id | name | number |    +----+------+--------+    |  5 | NULL |      5 |    |  6 | NULL |      6 |    +----+------+--------+    select name is NULL from t1 where number=5;    +--------------+    | name is NULL |    +--------------+    |            0 |    +--------------+    select name is NULL from t1 where number=6;    +--------------+    | name is NULL |    +--------------+    |            1 |    +--------------+

2) 统计包含 NULL 字段的值,NULL 值不包括在里面

    select count(*) from t1;    +----------+    | count(*) |    +----------+    |        6 |    +----------+    select count(name)from t1;    +-------------+    | count(name) |    +-------------+    |           5 |    +-------------+    select * from t1 where name is null;    +----+------+--------+    | id | name | number |    +----+------+--------+    |  6 | NULL |      6 |    +----+------+--------+

3) 如果你用 length 去统计一个 VARCHAR 的长度时,NULL 返回的将不是数字

    select length(name) from t1 where name is null;    +--------------+    | length(name) |    +--------------+    |         NULL |    +--------------+

总结:

NULL 本身是一个特殊值,MySQL 采用特殊的方法来处理 NULL 值。从理解肉眼判断,操作符运算等操作上,可能和我们预期的效果不一致。可能会给我们项目上的操作不符合预期。

你必须要使用 IS NULL / IS NOT NULL 这种与普通 SQL 大相径庭的方式去处理 NULL。

尽管在存储空间上,在索引性能上可能并不比空值差,但是为了避免其身上特殊性,给项目带来不确定因素,因此建议默认值不要使用 NULL

c310abbd8e881adbc6cef4638a3adfae.png

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/299301.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

.NET程序加壳的基本原理和方式浅析

.NET程序加壳的基本原理和方式浅析加壳程序是一种常用的保护应用程序的办法,确切的说是一种加密办法。取名为壳,意思是说这种对程序的保护办法就像植物种子的外壳,咱们运用一段程序将咱们的主程序包裹在其间,不能轻易被其他人看见…

如何开发一个学生成绩管理糸统(9)

这一节,我要说明的是在数据集中添加事务, 在这里说明一下事务的必要性: 大多数基于 web 的电子邮件客户端都使用一个网格列出每条消息,除了包含邮件的信息(主题、发送者等等)外,还包括一个复选框…

见识决定眼界,关注这些让你变得博学且有趣

全世界只有3.14 % 的人关注了爆炸吧知识真正决定人与人之间的差距的,其实是我们对事物的见识与内心的格局,见识的深浅决定人生的深浅,格局的大小决定了人生之路是宽是窄。今天给大家推荐几个有深度、有想法的公众号,希望能够给你带…

ELK太重?试试KFC日志采集

写在前面ELK三剑客(ElasticSearch,Logstash,Kibana)基本上可以满足日志采集、信息处理、统计分析、可视化报表等一些日志分析的工作,但是对我们来说……太重了,并且技术栈不是一路的。我们的场景是需要采集…

linux引导时输入特殊信息的含义

linux引导时输入特殊信息的含义:通常只有在缺省模式失败(屏幕一片混乱或者安装到某个阶段无法进行下去)的情况下会尝试这些模式。 对于一些支持的其他模式,参考文件/usr/share/doc/anaconda*/command-line.txt(如果安装…

ActionContext和ActionSupport的学习

2019独角兽企业重金招聘Python工程师标准>>> ActionContext和ActionSupport的学习 1.ActionContext中有众多的定义好的常量,就像是Constant类中定义的常量;诸如:session、Application、actionInvocation、Container等;…

中求和符号上下标_涨电脑知识:如何在word中编写复杂的公式,写论文必备技能...

我们在用word写资料时,比如论文、数据分析、报告等,经常需要插入一些公式,这些公式会含有一些特殊符号,比如根号、分式、求和等,这些特殊符号是不能直接用输入法来完成的,需要借助于word扩展的功能来帮助我…

菲尔兹奖第一华人!从抓虾仔到哈佛终身教授,他年少成名,获奖无数,造福我国数学教育数十年...

全世界只有3.14 % 的人关注了爆炸吧知识在数学界有这么一个人,他有着“数学天才”、“科学大师”、数学王国的“凯撒大帝”等一众称号。就连国际数学大师、阿贝尔奖获得者辛格都这样评价他说:“即使在哈佛,他一个人就是一个数学系&#xff01…

为什么我们总是忍不住要刷微信?

全世界只有3.14 % 的人关注了爆炸吧知识真正决定人与人之间的差距的,其实是我们对事物的见识与内心的格局,见识的深浅决定人生的深浅,格局的大小决定了人生之路是宽是窄。今天给大家推荐几个有深度、有想法的公众号,希望能够给你带…

22、多进程和多线程

 Android进程简介 Android会启动一个LINUX进程和一个主线程。默认的情况下,所 有该程序的组件都将在该进程中运行。当启动应用程序时,Linux会为每 一个程序单独分配一个进程,该进程默认只拥有一个主线程。 组件可以运行在当前进程中,也可以运行在其他进程中。组件运行在 哪个…

Docker小白到实战之常用命令演示,通俗易懂

前言上一篇大概认识了Docker,主要是从概念、架构、优点及流程方面进行阐述,并进行安装和体验;接下来就开始进行实操学习,在演示过程中会针对关键的知识点进行归纳和总结,这里先从常用命令说起,来吧&#xf…

今天这个日子,大多数人都不知道…

全世界只有3.14 % 的人关注了爆炸吧知识我是蝙蝠,身体虽小五毒俱全你确定要尝吗?我是果子狸,人们一度“谈我色变”但如今又被端上餐桌!我是野兔,人们说我很可爱我的肉却变成“野味”毛发变成皮草……今天,世…

Python办公自动化Day2-openpyxl

目录 文章声明⭐⭐⭐让我们开始今天的学习吧!常规操作添加数据遍历所有单元格数据合并/取消合并单元格添加/删除行与列移动指定范围单元格 文章声明⭐⭐⭐ 该文章为我(有编程语言基础,非编程小白)的 Python办公自动化自学笔记知识…

传递函数_使用python计算麦克风阵列信号的传递函数

使用python写了一个测试麦克风阵列传递函数的demo,有需要的自取。该代码使用了第三方库ThinkDSP。1. 传递函数首先解释下什么是传递函数:把具有线性特性的对象的输入与输出间的关系,用一个函数(输出波形的拉普拉斯变换与输入波形的拉普拉斯变…

中国数学竞赛史上最玩命的“赌徒”,为了国家荣誉,他不惜用生命换来了五次世界第一...

全世界只有3.14 % 的人关注了爆炸吧知识知识君今天,要跟大家介绍的是,北大历史上首位被授予博士学位的人,深受癌症折磨的同时还带领着中国学子连续5次站上世界顶端的人,他的故事,他的品格,值得被所有人记住…

javq接口_Java为什么要使用接口_java接口怎么使用

Java接口是什么Java接口是一系列方法的声明,是一些方法特征的集合,一个接口只有方法的特征没有方法的实现,因此这些方法可以在不同的地方被不同的类实现,而这些实现可以具有不同的行为(功能)。接口(英语:Interface)&am…

[(转)hystar整理]Entity Framework 教程

预备知识 2 LINQ技术 2 LINQ技术的基础 - C#3.0 2 自动属性 2 隐式类型 2 对象初始化器与集合初始化器 3 匿名类 3 扩展方法 4 Lambda表达式 4 .NET中的数据访问 4 DataSet方案 5 改进的的DataSet方案 5 手写代码通过ADO.NET2…

13岁上中科大,17岁攻读哈佛博士,“天才”尹希的开挂人生

全世界只有3.14 % 的人关注了爆炸吧知识2013年美国斯隆基金会(Alfred P. Sloan Foundation)颁发的美国斯隆研究奖获得者尹希,31岁哈佛最年轻的华人教授,获2017年“豪华版诺贝尔奖”之称的科学突破奖-物理学新视野奖,这年唯一的获奖华裔。知识…

强制升级?!.NET Core 2.1容器镜像将从Docker Hub中删除

前言.NET Core 2.1将于2021年8月21日结束支持,本来应该没什么影响,该怎么用继续用得了。但是,如果你在生产环境使用了.NET Core 2.1容器镜像,那就要注意了,从8月21日开始,.NET Core 2.1容器镜像将不再在Doc…

“史上“最疯狂”的顶级数学家,看完后忍不住感慨太神了”

▲ 点击查看说起世界上最顶级的数学家,你的脑海中会浮现的,大概是欧拉、高斯、香农等数学巨匠。但是要说起成就和神秘性兼备的,一定就是——称为印度之子的——拉马努金。1887年12月22日,拉马努金出生在印度一个穷困潦倒的家庭&am…