对于MySQL的一些个规范,某些公司建表规范中有一项要求是所有字段非空,意味着没有值的时候存储一个默认值。其实所有字段非空这么说应该是绝对了,应该说是尽可能非空,某些情况下不可能给出一个默认值。
那么这条要求,是基于哪些考虑因素,存储空间?相关增删查改操作的性能?亦或是其他考虑?该理论到底有没有道理或者可行性,本文就个人的理解,做一个粗浅的分析。

 

1,基于存储的考虑

这里对存储的分析要清楚MySQL数据行的存储格式,这里直接从这篇文章白嫖一部分结论,文章里分析的非常清楚(其实也是参考《MySQL技术内容Innodb存储引擎》)。
对于默认的Dynamic或者Compact格式的数据行结构,其行结构格式如下:
|变长字段长度列表(1~2字节)|NULL标志位(1字节)|记录头信息(5字节)|RowID(6字节)|事务ID(6字节)|回滚指针(7字节)|row content

1,对于变长字段,当相关的字段值为NULL时,相关字段不会占用存储空间。NULL值没有存储,不占空间,但是需要一个标志位(一行一个)。
2,对于变长字段,相关字段要求NOT NULL,存储成''的时候,也不占用空间,如果一个表中所有的字典都NOT NULL,行头不需要NULL的标志位
3,所有字段都是定长,不管是否要求为NOT NULL,都不需要标志位,同时不需要存储变长列长度

鉴于null值和非空(not null  default '')两种情况,如果一个字段存储的内容是空,也就是什么都没有,前者存储为null,后者存储为空字符串'',两者字段内容本身存储空间大小是一样的。
但是如果一个表中存储在可空字段的情况下,其对应的数据行的头部,都需要一个1字节的NULL标志位,这个就决定了存储同样的数据,如果允许为null,相比not null的情况下,每行多了一个字节的存储空间的。
这个因素或者就是某些公司或者个人坚持“所有表禁止null字段”这个信仰的原因之一(个人持否定态度,可以尝试将数据库中所有的字段都至为not null 然后default一个值后会不会鸡飞狗跳)。
这里不再去做“微观”的分析,直接从“宏观”的角度来看一下差异。

测试demo
直接创建结构一致,但是一个表字段not null,一个表字段为null,然后使用存储此过程,两张表同时按照null值与非null值1:10的比例写入数据,也就是说每10行数据中1行数据字段为null的方式写入600W行数据。

CREATE TABLE a
(
    id INT AUTO_INCREMENT,
    c2 VARCHAR(50) NOT NULL DEFAULT '',
    c3 VARCHAR(50) NOT NULL DEFAULT '',
    PRIMARY KEY (id)
);

CREATE TABLE b
(
    id INT AUTO_INCREMENT,
    c2 VARCHAR(50),
    c3 VARCHAR(50),
    PRIMARY KEY (id)
);


CREATE DEFINER=`root`@`%` PROCEDURE `create_test_data`(
    IN `loop_cnt` INT
)
LANGUAGE SQL
NOT DETERMINISTIC
CONTAINS SQL
SQL SECURITY DEFINER
COMMENT ''
BEGIN
    DECLARE v2 , v3 VARCHAR(36);
    
    START TRANSACTION;
    
        while loop_cnt>0 do
            SET v2 = UUID();
            SET v3 = UUID();

            
            if (loop_cnt MOD 10) = 0 then
                INSERT INTO a (c2,c3) VALUES(DEFAULT,DEFAULT);
                INSERT INTO b (c2,c3) VALUES(DEFAULT,DEFAULT);
            else
                INSERT INTO a (c2,c3) VALUES (v2,v3);
                INSERT INTO b (c2,c3) VALUES (v2,v3);
            END if ;
            
            SET loop_cnt=loop_cnt-1;
        END while;
    COMMIT;
    
View Code

相关文章:

  • 2022-01-14
  • 2022-12-23
  • 2021-10-11
  • 2022-12-23
  • 2021-08-10
  • 2021-10-09
  • 2021-12-10
  • 2021-12-10
猜你喜欢
  • 2022-12-23
  • 2022-12-23
  • 2021-07-06
  • 2021-08-11
  • 2021-10-02
  • 2021-09-15
  • 2021-04-21
相关资源
相似解决方案