设计数据库表时,是否允许字段为空很长时间我都认为无所谓,但在工作了很长时间后,才发现,其实这个很重要,不能想当然。


  之所以会有这个是否为空的选项,就是为了表示未知的情况。但是不是所有的未知情况都应该允许为空呢?

 例如,性别,使用1表示男,0表示女,空表示未知或者是用户没有选择。

 但又没有更好的方法呢?

      首先说下可空字段的问题,

查询条件就必须处理为空的情况,否则会出现一些很奇怪的问题。也就是说,几乎所有的判断都必须加上 is not null 或者时  is null 的判断。

         尤其时在使用子查询时,例如:      


select * from T_Test where Type1  in (select id from T_Test )



如果允许ID为空,那么子查询出来的就有null空值,结果可能永远查不出来数据,一个数据不能包含在 有null空值的集合里。同样not in 也查不出来数据。无形之中导致编写SQL变得复杂了。

如果为空,在部分数据库中会导致索引失效

3如果为空,为空也是需要存储空间的,导致空间变大,进而导致数据库系统查询分析变的复杂。

       4如果为空,在程序中也需要每次都判断是不是空,导致程序复杂了。

      例如为空的整形加上一个整形后,也是空,导致非常奇怪的计算错误。

public class Test1
    {
     public int? A{set;get;}
     public int? B { set; get; }
     public int? C{ set; get; }
    }
	
	  Test1 t1=new Test1 ();
      t1.A=1;
      var h = ConvertUtil.ToDecimal(t1.A + t1.B);



 以上计算的结果可能是null,导致一些非常奇怪的问题。

 那么有没有办法改进呢?

 其实在部分情况下可以使用默认值

alter table EAS.T_SurveyQuestion add  SQ_HasHtml INTEGER default 0 not null

例如,性别,使用1表示男,0表示女,2表示未知或者是用户没有选择。在默认值设置2

使用0未知,1表示男,2表示女因为大部分编程语言的数字类型的默认值0




这样的话,如果没有给相应的字段赋值,就会插入默认值,以上所有的问题也就解决了。使用默认值的思想可以解决很大一部分可为空的问题,但不是所有,具体还是要根据具体业务进行分析。