设计数据库表时,是否允许字段为空很长时间我都认为无所谓,但在工作了很长时间后,才发现,其实这个很重要,不能想当然。
之所以会有这个是否为空的选项,就是为了表示未知的情况。但是不是所有的未知情况都应该允许为空呢?
例如,性别,使用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
这样的话,如果没有给相应的字段赋值,就会插入默认值,以上所有的问题也就解决了。使用默认值的思想可以解决很大一部分可为空的问题,但不是所有,具体还是要根据具体业务进行分析。