Heim >Datenbank >MySQL-Tutorial > 数据库设计-从传统方式到事实表加维表的方式1

数据库设计-从传统方式到事实表加维表的方式1

WBOY
WBOYOriginal
2016-06-07 17:41:591177Durchsuche

引言事实表存放度量值和维度表的外键。维度表角度,分类。时间维度,地域维度,状态维度。旧的方式select*fromorderoinnerjoindistrictdono.discode=d.discodein


引言


事实表

存放度量值和维度表的外键。


维度表

角度,分类。时间维度,地域维度,状态维度。


旧的方式

select * from order o inner join district d on o.discode=d.discode inner join address a on o.addressid=a.addressid where o.createdate > '2012-2-5' and o.createdate 写死了存储过程,增加条件很困难。条件一变化,或者是有新增的字段,往往很多存储过程都需要修改,都要加上一个and条件,甚至是inner join一张新表,很是痛苦。总是思考有没有好办法,但总是没有想出来好的办法。


最近看数据仓库的建设,看到了事实表,维度表这些概念,结合自己做过的项目,有了一点点的感触。


其实一些标志位,状态,都可以看做是销售信息的一个维度。

通俗的说,就是不在订单表上条件字段了。以前一出现新的需求,就是直接在订单表中添加字段,订单表越来越大,总觉得很多字段和订单没有太多直接关系,但是想不出来该怎么办,香港空间,不知道该归结到那张表中,是新建一张表?还是其他什么表?总是很纠结,最后的结果往往还是添加在订单表中。


多条件查询,动态查询,不同维度综合查询。

其实就是不同维度的连接查询,条件越多,参与的维度越多。每增加一个维度,就连接一个维度表,这样就可以做成动态的,在代码中写好条件的拼接,数据库表的拼接,以后增加字段和表就几乎不用改动任何代码,包括程序代码和SQL代码,都不用手动维护了。


select * from order o inner join isb2c i on o.is=i.is inner join status s on o.statusid=s.statusid inner join address a on o.addressid=a.addressid


数据库设计方式


1 传统直接映射


在以前的数据设计中都会有一种bool的字段,代表的含义就是:【是】或者【否】。

举个例子说明一下,下面举一个产品表的例子。

好办,在表中加上一个字段,就想下图一样HasDiscount代表有无折扣。

 数据库设计-从传统方式到事实表加维表的方式1

插入一些数据,就想下面这样。

 数据库设计-从传统方式到事实表加维表的方式1


有一个场景就是查询产品,其中有一个条件就是有无折扣,条件有三种情况:


DECLARE @Has CHAR(1)--0无,1有,3忽略 SET @Has='3' IF(@Has='3') BEGIN SELECT p.ProductID, p.ProductName FROM SWB_Demo.dbo.T_Products p END ELSE BEGIN SELECT p.ProductID, p.ProductName FROM SWB_Demo.dbo.T_Products p WHERE p.HasDiscount=@Has END


上面SQL中的@Has还可以写成判断是否为null,反正只要是区别于0和1的其他值都可以实现同样的效果。


好像看起来还可以,但是需求变化了,需要再加上一个bool的字段,在查询场景也有上面的三种情况。

好吧,又是一个分支,继续添加。

DECLARE @HasDiscount CHAR(1)--0无,1有,3忽略 SET @HasDiscount='3' DECLARE @Has CHAR(1)--0无,1有,3忽略 SET @Has='1' IF(@Has='3') BEGIN IF(@HasDiscount='3') BEGIN SELECT p.ProductID, p.ProductName FROM SWB_Demo.dbo.T_Products p END ELSE BEGIN SELECT p.ProductID, p.ProductName FROM SWB_Demo.dbo.T_Products p WHERE p.HasDiscount=@HasDiscount END END ELSE BEGIN IF(@HasDiscount='3') BEGIN SELECT p.ProductID, p.ProductName FROM SWB_Demo.dbo.T_Products p where p.Has=@Has END ELSE BEGIN SELECT p.ProductID, p.ProductName FROM SWB_Demo.dbo.T_Products p WHERE p.HasDiscount=@HasDiscount AND p.Has=@Has END END

好吧,需求被我搞定了,然后说:“再也不要添加这样的属性了,否则这段SQL谁也维护不了了,我要逃跑了!”。但是需求是肯定会变的,而且在很多情况这样的属性都少不了,那怎么办呢,难道大家都是这么做的吗?

好像听说人家都不用写存储过程,至少是很少写的,美国空间,怎么我这个地方就成了噩梦了呢。

听说好像可以用代码生成SQL,网站空间,只要封装的好,就可以实现添加表,添加字段,不用每次修改SQL,既然有,肯定是可以实现的,至少在某种程度上可以减少开发量,因为这种属性是没有办法穷举的。


2 事实表加维表


经过这几天对于事实表和维表的学习,有了一点小的想法,所以分享一下。

首先将产品表的结构修改如下。

插入下面的数据。

 数据库设计-从传统方式到事实表加维表的方式1


这时候SQL就可以写成下面的样子。

--不考虑是否打折这个条件 SELECT * FROM SWB_Demo.dbo.T_Products p WHERE p.ProductName LIKE '%果%' --考虑是否打折这个条件 SELECT * FROM SWB_Demo.dbo.T_Products p INNER JOIN SWB_Demo.dbo.T_ProductHasDiscount php ON p.ProductID=php.ProductID INNER JOIN SWB_Demo.dbo.T_HasDiscount ph ON php.HasID=ph.HasID AND ph.HasNot='1' WHERE p.ProductName LIKE '%果%'


中间的连接打折表和打折关系表的部分就可以动态拼接,整个SQL语句的生成用代码来实现,不用每次变动就修改SQL了,是不是更好一点呢?



本文出自 “突破中的IT结构师” 博客,请务必保留此出处

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn