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扩展的功能来帮助我…

6、struts.properties配置详解

在Struts2的核心包中org\apache\struts2文件夹下可以找到Struts2的一个默认配置文件default.properties。有时为了调试方便我们可以更改部分默认内容。具体的方法是在工程的WEB-INF/classes文件夹下简历一个struts.properties文件,并将要修改的信息配置到该文件中 s…

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

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

关于string

string是一种很特殊的数据类型,它既是基元类型又是引用类型,在编译以及运行时,.Net都对它做了一些优化工作。  一.恒定的字符串要想比较全面的了解stirng类型,首先要清楚.Net中的值类型与引用类型。在C#中&#xff0…

python第七天--字符串的方法与注释

capitalize() 把字符串的第一个字符改为大写casefold() 把整个字符串的所有字符改为小写center(width) 将字符串居中,并使用空格填充至长度width的新字符串count(sub[,start[,end]]) 返回sub在字符串里边出现的次数,start和end参数表示范围&#xff…

android的热点分配ip_Android 得到连接热点的ip的方法

下面给大家介绍Android 得到连接热点的ip的方法 ,具体代码如下所示:WifiManager wifiManager (WifiManager) this.getSystemService(Context.WIFI_SERVICE);if (!wifiManager.isWifiEnabled()) {System.out.println("");wifiManager.setWifiE…

【SQL基础】T-SQL函数类型——元数据函数

一般来说,元数据函数返回的是有关指定数据库和数据对象的信息。下面介绍几种元数据函数。 1、COL_NAME(tab_id,col_id),返回表tab_id的tab_id的列名。 例:selectCOL_NAME(OBJECT_ID(employees),3); 结果为’FirstName’ 2、COLUMNPROPERTY(id…

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

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

22、多进程和多线程

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

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

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

lumen 配置数据库结果自动转数组_lumen 数据库操作 Cannot use object of type stdClass as array...

你可能记得,操作数据库时$dataList 什么什么 ->get();能查询到数据 数据结果为数组加stdClass类型你使用 $dataList $dataList->toArray();进行数据转化结果你发现,没有正确转化,你再到里面去转化,但结果证明也是徒劳foreach ($allDa…

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

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

PostgreSQL表的行数统计

PostgreSQL表的行数统计 在很多情况下我们需要知道一个表的记录数有多少。如果你发现你有这样的需求,你还应该问问这样的统计的精确度到底又多高。如果你在做会计报表,你需要非常的精确。如果你做一个网页的记数器,可能有一些误差也是允许的…

SharePoint at .NET技术大会

在这个月上海举行的.NET技术大会上,我将奉献一节名为《基于SharePoint的Web应用开发模型》的课程。由于大会的定位是“面向企业级.NET开发深度应用”,我相信大家想听的一定不是单纯的介绍SharePoint Server,或是怎么做一个Web Part。思来想去…