NULL 对外部程序来说,具体为不知道、不确切的、无法表述的值。所以在很多家公司的开发规范里都明确规定了,必须为 NOT NULL。
其实用到 NULL 的场景都可以转换为有意义的字符或者数值,一是有利用数据的易读性以及后期的易维护性;二是降低 SQL 语句的编写难度。
关于 NULL 的特性如下:
1 参与 NULL 字段拼接的结果都为 NULL,预期的可能会有差异
预想把字段 r1 做个拼接,再插入到新的表 t3 里,结果 t3 表的记录全为 NULL,跟预期不符。
mysql> show create table t1\G
1 row
Table: t1
Create Table: CREATE TABLE `t1` (
`r1` varchar(10) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
1 row in set (000 sec)
mysql> show create table t2\G
1 row
Table: t2
Create Table: CREATE TABLE `t2` (
`r1` varchar(10) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
1 row in set (000 sec)
mysql> create table t3 like t1
Query OK, 0 rows affected (004 sec)
mysql> insert into t3 select concat(r1,'database') from t1 limit 2;
Query OK, 2 rows affected (002 sec)
Records: 2 Duplicates: 0 Warnings: 0
mysql> select from t3;
+------+
| r1 |
+------+
| NULL |
| NULL |
+------+
2 rows in set (000 sec)
那正确的方法如下,对 NULL 用函数 IFNULL 特殊处理。
mysql> insert into t3 select concat(ifnull(r1,''),'database') from t1 limit 2;
Query OK, 2 rows affected (001 sec)
Records: 2 Duplicates: 0 Warnings: 0
mysql> select from t3;
+----------+
| r1 |
+----------+
| database |
| database |
+----------+
2 rows in set (000 sec)
2 对于包含 NULL 列的求 COUNT 值也不准确
t1 和 t2 的记录数是一样的,但是字段 r1 包含了 NULL,这导致结果忽略了这些值。
mysql> select count(r1) as rc from t1;
+-------+
| rc |
+-------+
| 16384 |
+-------+
1 row in set (001 sec)
mysql> select count(r1) as rc from t2;
+-------+
| rc |
+-------+
| 32768 |
+-------+
1 row in set (003 sec)
这时候我们可能想到了,正确的方法是用 NULL 相关函数处理,
mysql> select count(ifnull(r1,'')) as rc from t1;
+-------+
| rc |
+-------+
| 32768 |
+-------+
1 row in set (003 sec)
或者是直接用 COUNT() 包含了所有可能的值
mysql> select count() as rc from t1;
+-------+
| rc |
+-------+
| 32768 |
+-------+
1 row in set (002 sec)
当然了不仅仅是 COUNT,除了 NULL 相关的函数,大部分对 NULL 处理都不友好。
所以其实从上面两点来看,NULL 的处理都得特殊处理,额外增加了编写 SQL 的难度。
3 包含 NULL 的索引列
对包含 NULL 列建立索引,比不包含的 NULL 的字段,要多占用一个 BIT 位来存储。
示例
key_len 分别为 43 和 42,t1 比 t2 多了一个字节,那这里可能有人要问了,不是说占了一个 BIT 位吗?那为什么多了一个字节?可以关注我上一篇文章(第02期:MySQL 数据类型的艺术 - 大对象字段)关于 BIT 的详细描述。
mysql> pager grep -i 'key_len'
PAGER set to 'grep -i 'key_len''
mysql> explain select from t1 where r1 = ''\G
key_len: 43
1 row in set, 1 warning (000 sec)
mysql> explain select from t2 where r1 = ''\G
key_len: 42
1 row in set, 1 warning (000 sec)
4 各存储引擎相关的对 NULL 的处理
在 MySQL 80 发布后,仅有 InnoDB、MyISAM 和 Memory 支持对包含 NULL 列的索引,其他引擎不支持。比如 NDB。
alert table TableName add FieldName varchar(100) not null
改成
alter table TableName add FieldName varchar(100) not null
我自己测试过了。。
alert table TableName add FieldName varchar(100) not null
是可以创建列的
1、真正的空值,也就是“没有输入的值”,可以出现在大多数类型的字段中(如果没有别的约束条件),SQL server中表示为null,显示为<NULL>,手工在SQL server企业管理器中输入的方法是按Ctrl+0。它在NET中对应SystemDBNullValue。在T-SQL命令中,判断一个值是不是空值,要用“is null”而不是“= null”;处理空值有个ISNULL函数,它使用指定的值替换null。用ADONET从数据库得到的空值无法自动转化为空字符串或Nothing,须手动检测:如果得到SystemDBNullValue,则赋给数据对象Nothing或其它自定义的有意义的值。
2、空字符串(零长度字符串),只出现在字符串类型(如nvarchar)的字段中,SQL server中表示为'',显示为空白,手工在SQL server企业管理器中输入时清空一个单元格即可。它在NET中对应SystemStringEmpty,也就是我们常用的""。在T-SQL命令中处理空字符串和处理一般的字符串没什么区别。用ADONET从数据库得到的空字符串也和一般的字符串没什么区别。
数据库设计里的非空都是 null
以上就是关于如何在mysql中一次性查出某表中所有字段的非空个数全部的内容,包括:如何在mysql中一次性查出某表中所有字段的非空个数、SQL语句创建非空字段、数据库字段可以为空,指的是什么等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)