为什么表设计时必须把字段定义为NOT NULL并设默认值

为什么表设计时必须把字段定义为NOT NULL并设默认值

空间占用的坑

  • 空’'在存储过程中是不会占用空间的,但是NULL会。就像一个杯子,空表示杯子是真空的,NULL表示装的空气。

  • mysql> SELECT length('1'),length(NULL),length('');
    
    +-------------+--------------+------------+
    | length('1') | length(NULL) | length('') |
    +-------------+--------------+------------+
    |           1 | NULL         |          0 |
    +-------------+--------------+------------+
    1 row in set
    
    mysql> 
    

查询的坑

  • 如果要查询表的NULL需要使用 is nullis not null,如果直接使用=/!=/in/not inl将查询不到值

  • mysql> SELECT * FROM `user`;
    +----+------+-----+---------+
    | id | name | age | address |
    +----+------+-----+---------+
    |  1 | wyf  |  32 | 合肥    |
    |  2 | xx   |  31 | 北京    |
    |  3 | yy   |  30 | 上海    |
    |  4 | zz   |  11 |         |
    |  5 | aa   |  21 | NULL    |
    +----+------+-----+---------+
    5 rows in set
    
    mysql> SELECT * FROM `user` WHERE address IS NULL;
    +----+------+-----+---------+
    | id | name | age | address |
    +----+------+-----+---------+
    |  5 | aa   |  21 | NULL    |
    +----+------+-----+---------+
    1 row in set
    
    mysql> SELECT * FROM `user` WHERE address = NULL;
    Empty set
    
    mysql> 
    

NULL统计的坑

  • 如果使用count()等统计函数,将不会统计NULL。如下,一共有5条数据,统计address就只返回4。

  • mysql> SELECT * FROM `user`;
    +----+------+-----+---------+
    | id | name | age | address |
    +----+------+-----+---------+
    |  1 | wyf  |  32 | 合肥    |
    |  2 | xx   |  31 | 北京    |
    |  3 | yy   |  30 | 上海    |
    |  4 | zz   |  11 |         |
    |  5 | aa   |  21 | NULL    |
    +----+------+-----+---------+
    5 rows in set
    
    mysql> SELECT COUNT(address) FROM `user`;
    +----------------+
    | COUNT(address) |
    +----------------+
    |              4 |
    +----------------+
    1 row in set
    
    mysql> 
    

索引的坑

  • Mysql的索引会为NULL值做特殊处理,导致整个索引的查询效率下降。如果是语句中有 is null会使用索引,如果语句中有is not null则会导致索引失效,如下:

  • 查看索引:

  • mysql> show index from user;
    +-------+------------+-------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
    | Table | Non_unique | Key_name    | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
    +-------+------------+-------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
    | user  |          0 | PRIMARY     |            1 | id          | A         |           5 | NULL     | NULL   |      | BTREE      |         |               |
    | user  |          1 | idx_name    |            1 | name        | A         |           5 | NULL     | NULL   | YES  | BTREE      |         |               |
    | user  |          1 | idx_address |            1 | address     | A         |           5 | NULL     | NULL   | YES  | BTREE      |         |               |
    +-------+------------+-------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
    3 rows in set
    
  • is null 会使用索引

  • mysql> explain select * from user where address is null;
    +----+-------------+-------+------------+------+---------------+-------------+---------+-------+------+----------+-----------------------+
    | id | select_type | table | partitions | type | possible_keys | key         | key_len | ref   | rows | filtered | Extra                 |
    +----+-------------+-------+------------+------+---------------+-------------+---------+-------+------+----------+-----------------------+
    |  1 | SIMPLE      | user  | NULL       | ref  | idx_address   | idx_address | 1023    | const |    1 |      100 | Using index condition |
    +----+-------------+-------+------------+------+---------------+-------------+---------+-------+------+----------+-----------------------+
    1 row in set
    
  • is not null 不会使用索引

  • mysql> explain select * from user where address is not null;
    +----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+
    | id | select_type | table | partitions | type | possible_keys | key  | key_len | ref  | rows | filtered | Extra       |
    +----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+
    |  1 | SIMPLE      | user  | NULL       | ALL  | idx_address   | NULL | NULL    | NULL |    5 |       80 | Using where |
    +----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+
    1 row in set
    
    mysql> 
    
  • 33
    点赞
  • 36
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

IT枫斗者

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值