在很多系统中用数字类型表示日期类型的字段设计。这样设计会带来一定的问题,现具体说明一下。
1.存储空间
在传统设计中,经常有类似的设计,很多设计的初衷是为了节省存储空间。下面举例观察一下,不同字段类型的存储空间消耗。oracle培训
示例
SQL> create table t1 ( c1 int,c2 number,c3 date);
SQL> insert into t1 values(20110101,20110101,to_date('20110101','yyyymmdd'));
SQL> commit;
SQL> select dump(c1),dump(c2),dump(c3) from t1;
DUMP(C1)
--------------------------------------------------------------------------------
DUMP(C2)
--------------------------------------------------------------------------------
DUMP(C3)
--------------------------------------------------------------------------------
Typ=2 Len=5: 196,21,12,2,2 //占用5个字节
Typ=2 Len=5: 196,21,12,2,2 //占用5个字节
Typ=12 Len=7: 120,111,1,1,1,1,1 //占用7个字节
结论
采用这种设计,会在一定程度上节省空间,但是整体收益并不是很明显。
2.数据质量
示例
SQL> insert into t1(c1) values(20119999); …ok
SQL> insert into t1(c3) values(20119999); …err
结论
采用这种写法,会”屏蔽”字段的日期属性。在开发的过程中容易导致因为异常日期数据(合法数字),造成数据质量下降。
3.字段加减
示例
SQL> select * from t1;
C1 C2 C3
---------- --------- ---------
20110101 20110101 01-JAN-11
20110202 20110202 02-FEB-11
SQL> select c1+50,c3+50 from t1;
C1+50 C3+50
---------- ---------
20110151 20-FEB-11
20110252 24-MAR-11
*显然对于从数字表示的日期,简单的加法就造成了”歧义”。
结论
针对日期类型的加、减法,日期之间的减法等,有其特殊的含义,用数字代表,往往会带来错误的结果。
4.计算选择率
示例
SQL> create table t1(d1 date,n1 number);
SQL> select * from t1 where rownum<5;
D1 N1
------------------- ------------
2001-06-02 00:00:00 20010602
2001-06-03 00:00:00 20010603
2001-06-04 00:00:00 20010604
2001-06-05 00:00:00 20010605
*两列列分别为日期、数字类型,但保存的都是"日期"含义的数据。
*在日期类型对,对选择基数的计算明显出现异常。有正常的8”天”偏差到了396”天”。其直接后果导致优化器可能选择了错误的执行计划。
结论
使用错误的数据类型保存(例如:用数字保存日期类型数据),这往往会造成优化器对范围的判断错误。虽然可以采用直方图或FBI的方式解决,但是这会花费额外的代价且有一定局限性。
posted on 2013-08-13 14:49
亲爱的小孩 阅读(106)
评论(0) 编辑 收藏