当前位置:网站首页>MySQL does not recommend setting the column default value to null. Why on earth is this

MySQL does not recommend setting the column default value to null. Why on earth is this

2022-06-13 07:07:00 guangsu.

MySQL Not recommended NULL What is the default value of the column

The answer you usually hear is Used NULL Values will invalidate the index , But if you actually test it , You will know IS NULL Use index . So there are loopholes in the above statement .

The anxious person pulls to the bottom to see the conclusion

Preface

Null is a special constraint of columns.
The columns in table will be added null constrain if you do not define the column with “not null” key words explicitly
when creating the table.Many programmers like to define columns by default
because of the conveniences(reducing the judgement code of nullibility) what consequently
cause some uncertainty of query and poor performance of database.

NULL Value is a special constraint on Columns , When we create a new column , If you don't explicitly use keywords not null Declare the data column ,Mysql By default, we will add NULL constraint .
Some developers create datasheets , Use directly because of laziness Mysql Default recommended settings for .( That is to allow fields to use NULL value ). And this bad habit is easy to use NULL In this scenario, we can get uncertain query results and cause database performance degradation .

Introduce

Null is null means it is not anything at all,we cannot think of null is equal to ‘’ and they are totally different.
MySQL provides three operators to handle null value:“IS NULL”,“IS NOT NULL”,"<=>" and a function ifnull().
IS NULL: It returns true,if the column value is null.
IS NOT NULL: It returns true,if the columns value is not null.
<=>: It’s a compare operator similar with “=” but not the same.It returns true even for the two null values.
(eg. null <=> null is legal)
IFNULL(): Specify two input parameters,if the first is null value then returns the second one.
It’s similar with Oracle’s NVL() function.

NULL It doesn't mean there's nothing , We need to pay attention NULL Follow ''( Null value ) It's two completely different values .MySQL It can be operated in NULL There are three main value operators .

  • IS NULL
  • IS NOT NULL
  • <=> Spaceship operators , This operator is very similar to =,select NULL<=>NULL Can return true, however select NULL=NULL return false.
  • IFNULL A function . How to use it? Check it by yourself … Anyway, I will

Example

Null never returns true when comparing with any other values except null with “<=>”.
NULL By comparing any operator with other values, you get NULL, except <=>.

 1 ([email protected] mysql3306.sock)[zlm]>create table test_null(
 2     -> id int not null,
 3     -> name varchar(10)
 4     -> );
 5 Query OK, 0 rows affected (0.02 sec)
 6 
 7 ([email protected] mysql3306.sock)[zlm]>insert into test_null values(1,'zlm');
 8 Query OK, 1 row affected (0.00 sec)
 9 
10 ([email protected] mysql3306.sock)[zlm]>insert into test_null values(2,null);
11 Query OK, 1 row affected (0.00 sec)
12 
13 ([email protected] mysql3306.sock)[zlm]>select * from test_null;
14 +----+------+
15 | id | name |
16 +----+------+
17 |  1 | zlm  |
18 |  2 | NULL |
19 +----+------+
20 2 rows in set (0.00 sec)
21 // --------------------------------------> This is very representative <----------------------
22 ([email protected] mysql3306.sock)[zlm]>select * from test_null where name=null;
23 Empty set (0.00 sec)
24 
25 ([email protected] mysql3306.sock)[zlm]>select * from test_null where name is null;
26 +----+------+
27 | id | name |
28 +----+------+
29 |  2 | NULL |
30 +----+------+
31 1 row in set (0.00 sec)
32 
33 ([email protected] mysql3306.sock)[zlm]>select * from test_null where name is not null;
34 +----+------+
35 | id | name |
36 +----+------+
37 |  1 | zlm  |
38 +----+------+
39 1 row in set (0.00 sec)
40 
41 ([email protected] mysql3306.sock)[zlm]>select * from test_null where null=null;
42 Empty set (0.00 sec)
43 
44 ([email protected] mysql3306.sock)[zlm]>select * from test_null where null<>null;
45 Empty set (0.00 sec)
46 
47 ([email protected] mysql3306.sock)[zlm]>select * from test_null where null<=>null;
48 +----+------+
49 | id | name |
50 +----+------+
51 |  1 | zlm  |
52 |  2 | NULL |
53 +----+------+
54 2 rows in set (0.00 sec)
55  //null<=>null always return true,it's equal to "where 1=1".  

Null means “a missing and unknown value”.Let’s see details below.
NULL Represents an uncertain value , Even if it's two NULL, It's not necessarily the same .( Does it look similar? C Uninitialized local variables in )

 1 ([email protected] mysql3306.sock)[zlm]>SELECT 0 IS NULL, 0 IS NOT NULL, '' IS NULL, '' IS NOT NULL;
 2 +-----------+---------------+------------+----------------+
 3 | 0 IS NULL | 0 IS NOT NULL | '' IS NULL | '' IS NOT NULL |
 4 +-----------+---------------+------------+----------------+
 5 |         0 |             1 |          0 |              1 |
 6 +-----------+---------------+------------+----------------+
 7 1 row in set (0.00 sec)
 8 
 9 //It's not equal to zero number or vacant string.
10 //In MySQL,0 means fasle,1 means true.
11 
12 ([email protected] mysql3306.sock)[zlm]>SELECT 1 = NULL, 1 <> NULL, 1 < NULL, 1 > NULL;
13 +----------+-----------+----------+----------+
14 | 1 = NULL | 1 <> NULL | 1 < NULL | 1 > NULL |
15 +----------+-----------+----------+----------+
16 |     NULL |      NULL |     NULL |     NULL |
17 +----------+-----------+----------+----------+
18 1 row in set (0.00 sec)
19 
20 //It cannot be compared with number.
21 //In MySQL,null means false,too.

It truns null as a result if any expression contains null value.
Any expression that has a return value has NULL Participation time , Will get another NULL value .

 1 ([email protected] mysql3306.sock)[zlm]>select ifnull(null,'First is null'),ifnull(null+10,'First is null'),ifnull(concat('abc',null),'First is null');
 2 +------------------------------+---------------------------------+--------------------------------------------+
 3 | ifnull(null,'First is null') | ifnull(null+10,'First is null') | ifnull(concat('abc',null),'First is null') |
 4 +------------------------------+---------------------------------+--------------------------------------------+
 5 | First is null                | First is null                   | First is null                              |
 6 +------------------------------+---------------------------------+--------------------------------------------+
 7 1 row in set (0.00 sec)
 8 
 9   //null value needs to be disposed with ifnull() function,what usually causes sql statement more complex.
 10  //As we all know,MySQL does not support funcion index.Therefore,indexes on the column may not be used.That's really worse.

It’s diffrent when using count(*) & count(null column).
Use count(*) perhaps count(null column) The results are different ,count(null column)<=count(*).

 1 ([email protected] mysql3306.sock)[zlm]>select count(*),count(name) from test_null;
 2 +----------+-------------+
 3 | count(*) | count(name) |
 4 +----------+-------------+
 5 |        2 |           1 |
 6 +----------+-------------+
 7 1 row in set (0.00 sec)
 8 
 9 //count(*) returns all rows ignore the null while count(name) returns the non-null rows in column "name".
10 // This will also leads to uncertainty if someone is unaware of the details above.
  If the user is right about NULL The attribute is not familiar with , It's easy to count the wrong results .

When using distinct,group by,order by,all null values are considered as the same value.
although select NULL=NULL As the result of the false, But when we use distinct,group by,order by when ,NULL It's considered the same again value .

 1 ([email protected] mysql3306.sock)[zlm]>insert into test_null values(3,null);
 2 Query OK, 1 row affected (0.00 sec)
 3 
 4 ([email protected] mysql3306.sock)[zlm]>select distinct name from test_null;
 5 +------+
 6 | name |
 7 +------+
 8 | zlm  |
 9 | NULL |
10 +------+
11 2 rows in set (0.00 sec)
12 
13 //Two rows of null value returned one and the result became two.
14 
15 ([email protected] mysql3306.sock)[zlm]>select name from test_null group by name;
16 +------+
17 | name |
18 +------+
19 | NULL |
20 | zlm  |
21 +------+
22 2 rows in set (0.00 sec)
23 
24 //Two rows of null value were put into the same group.
25 //By default,group by will also sort the result(null row showed first).
26 
27 ([email protected] mysql3306.sock)[zlm]>select id,name from test_null order by name;
28 +----+------+
29 | id | name |
30 +----+------+
31 |  2 | NULL |
32 |  3 | NULL |
33 |  1 | zlm  |
34 +----+------+
35 3 rows in set (0.00 sec)
36 
37 //Three rows were sorted(two null rows showed first). 

MySQL supports to use index on column which contains null value(what’s different from oracle).
MySQL Support in containing NULL Use the index on the column of value , however Oracle I won't support it . This is what we usually say if the column contains NULL That will invalidate the index .
Strictly speaking , This sentence is true of MySQL It's not accurate .

 1 ([email protected] mysql3306.sock)[sysbench]>show tables;
 2 +--------------------+
 3 | Tables_in_sysbench |
 4 +--------------------+
 5 | sbtest1            |
 6 | sbtest10           |
 7 | sbtest2            |
 8 | sbtest3            |
 9 | sbtest4            |
10 | sbtest5            |
11 | sbtest6            |
12 | sbtest7            |
13 | sbtest8            |
14 | sbtest9            |
15 +--------------------+
16 10 rows in set (0.00 sec)
17 
18 ([email protected] mysql3306.sock)[sysbench]>show create table sbtest1\G
19 *************************** 1. row ***************************
20        Table: sbtest1
21 Create Table: CREATE TABLE `sbtest1` (
22   `id` int(11) NOT NULL AUTO_INCREMENT,
23   `k` int(11) NOT NULL DEFAULT '0',
24   `c` char(120) NOT NULL DEFAULT '',
25   `pad` char(60) NOT NULL DEFAULT '',
26   PRIMARY KEY (`id`),
27   KEY `k_1` (`k`)
28 ) ENGINE=InnoDB AUTO_INCREMENT=100001 DEFAULT CHARSET=utf8
29 1 row in set (0.00 sec)
30 
31 ([email protected] mysql3306.sock)[sysbench]>alter table sbtest1 modify k int null,modify c char(120) null,modify pad char(60) null;
32 Query OK, 0 rows affected (4.14 sec)
33 Records: 0  Duplicates: 0  Warnings: 0
34 
35 ([email protected] mysql3306.sock)[sysbench]>insert into sbtest1 values(100001,null,null,null);
36 Query OK, 1 row affected (0.00 sec)
37 
38 ([email protected] mysql3306.sock)[sysbench]>explain select id,k from sbtest1 where id=100001;
39 +----+-------------+---------+------------+-------+---------------+---------+---------+-------+------+----------+-------+
40 | id | select_type | table   | partitions | type  | possible_keys | key     | key_len | ref   | rows | filtered | Extra |
41 +----+-------------+---------+------------+-------+---------------+---------+---------+-------+------+----------+-------+
42 |  1 | SIMPLE      | sbtest1 | NULL       | const | PRIMARY       | PRIMARY | 4       | const |    1 |   100.00 | NULL  |
43 +----+-------------+---------+------------+-------+---------------+---------+---------+-------+------+----------+-------+
44 1 row in set, 1 warning (0.00 sec)
45 
46 ([email protected] mysql3306.sock)[sysbench]>explain select id,k from sbtest1 where k is null;
47 +----+-------------+---------+------------+------+---------------+------+---------+-------+------+----------+--------------------------+
48 | id | select_type | table   | partitions | type | possible_keys | key  | key_len | ref   | rows | filtered | Extra                    |
49 +----+-------------+---------+------------+------+---------------+------+---------+-------+------+----------+--------------------------+
50 |  1 | SIMPLE      | sbtest1 | NULL       | ref  | k_1           | k_1  | 5       | const |    1 |   100.00 | Using where; Using index |
51 +----+-------------+---------+------------+------+---------------+------+---------+-------+------+----------+--------------------------+
52 1 row in set, 1 warning (0.00 sec)
53 
54 //In the first query,the newly added row is retrieved( retrieval ) by primary key.
55 //In the second query,the newly added row is retrieved by secondary key "k_1"
56 // It has been proved that indexes can be used on the columns which contain null value.
    adopt explain  You can see  mysql Support contains NULL Use the index on the column of value  
57 //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.

This is an example of my own testing .

mysql> select * from test_1;
+-----------+------+------+
| name      | code | id   |
+-----------+------+------+
| gaoyi     | wo   |    1 |
| gaoyi     | w    |    2 |
| chuzhong  | wo   |    3 |
| chuzhong  | w    |    4 |
| xiaoxue   | dd   |    5 |
| xiaoxue   | dfdf |    6 |
| sujianhui | su   |   99 |
| sujianhui | NULL |   99 |
+-----------+------+------+
8 rows in set (0.00 sec)

mysql> explain select * from test_1 where code is NULL;
+----+-------------+--------+------------+------+---------------+------------+---------+-------+------+----------+-----------------------+
| id | select_type | table  | partitions | type | possible_keys | key        | key_len | ref   | rows | filtered | Extra                 |
+----+-------------+--------+------------+------+---------------+------------+---------+-------+------+----------+-----------------------+
|  1 | SIMPLE      | test_1 | NULL       | ref  | index_code    | index_code | 161     | const |    1 |   100.00 | Using index condition |
+----+-------------+--------+------------+------+---------------+------------+---------+-------+------+----------+-----------------------+
1 row in set, 1 warning (0.00 sec)

mysql> explain select * from test_1 where code is not NULL;
+----+-------------+--------+------------+-------+---------------+------------+---------+------+------+----------+-----------------------+
| id | select_type | table  | partitions | type  | possible_keys | key        | key_len | ref  | rows | filtered | Extra                 |
+----+-------------+--------+------------+-------+---------------+------------+---------+------+------+----------+-----------------------+
|  1 | SIMPLE      | test_1 | NULL       | range | index_code    | index_code | 161     | NULL |    7 |   100.00 | Using index condition |
+----+-------------+--------+------------+-------+---------------+------------+---------+------+------+----------+-----------------------+
1 row in set, 1 warning (0.00 sec)

mysql> explain select * from test_1 where code='dd';
+----+-------------+--------+------------+------+---------------+------------+---------+-------+------+----------+-----------------------+
| id | select_type | table  | partitions | type | possible_keys | key        | key_len | ref   | rows | filtered | Extra                 |
+----+-------------+--------+------------+------+---------------+------------+---------+-------+------+----------+-----------------------+
|  1 | SIMPLE      | test_1 | NULL       | ref  | index_code    | index_code | 161     | const |    1 |   100.00 | Using index condition |
+----+-------------+--------+------------+------+---------------+------------+---------+-------+------+----------+-----------------------+
1 row in set, 1 warning (0.00 sec)

mysql> explain select * from test_1 where code like "dd%";
+----+-------------+--------+------------+-------+---------------+------------+---------+------+------+----------+-----------------------+
| id | select_type | table  | partitions | type  | possible_keys | key        | key_len | ref  | rows | filtered | Extra                 |
+----+-------------+--------+------------+-------+---------------+------------+---------+------+------+----------+-----------------------+
|  1 | SIMPLE      | test_1 | NULL       | range | index_code    | index_code | 161     | NULL |    1 |   100.00 | Using index condition |
+----+-------------+--------+------------+-------+---------------+------------+---------+------+------+----------+-----------------------+
1 row in set, 1 warning (0.00 sec)

Summary summary

null value always leads to many uncertainties when disposing sql statement.It may cause bad performance accidentally.

Use... In the column NULL Values can easily trigger uncontrolled events , Sometimes it can seriously slow down the performance of the system .

for example :

  • null value will not be estimated in aggregate function() which may cause inaccurate results.
    Yes, it contains NULL Value of the column for statistical calculation ,eg. count(),max(),min(), The results didn't meet our expectations .
  • null value will influence the behavior of the operations such as “distinct”,“group by”,“order by” which causes wrong sort.
    Interference sequencing , grouping , De duplication results .
  • null value needs ifnull() function to do judgement which makes the program code more complex.
    Sometimes in order to eliminate NULL The technical debt that comes with it , We need to be in SQL Use in IFNULL() To make sure the results are manageable , But it makes the program complicated .
  • null value needs a extra 1 byte to store the null information in the rows.
    NULL The value is stored in the original field space , It's an extra byte to mark , This field adds NULL constraint .( It's like an extra marker bit )

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.

According to the above shortcomings , We do not recommend setting... In columns NULL As the default value of the column , You can use NOT NULL Remove the default settings , Use 0 perhaps '' Empty string instead of NULL.

Reference material

Original address https://www.cnblogs.com/aaron8219/p/9259379.html

原网站

版权声明
本文为[guangsu.]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/02/202202270550304995.html