|
前面其实已经把数据库宽表开发写得差不多了。可能不少人认为已经写完了。事实上并非如此。前面只是一个留存率的报表。如果还要加上同比呢?环比呢?是不是打算每个报表都写一个存储过程呢?如果想把这些报表数据都放在同一个表里,又应该如何处理呢?
这一节,我们就来探讨这个问题。
一般来说,当涉及这么多报表的时候,如果不希望创建多个表的话,那么通常会考虑重新设计表。这时候有两种解决方式。一种是沿用前面的模式,不同的是,会通过一个报表ID或者报表名称作为主键或者索引来查询。例如:
报表ID | 报表名称 | 报表日期 | 维度1 | 维度2 | 值1 | 值2 | 值3 | 值4 | 值5 | 值6 | 值7 | 1 | 7天留存率 | 20200627 | 华东 | 上海 | …… | …… | …… | …… | …… | …… | …… | 1 | 7天留存率 | 20200627 | 华南 | 广州 | …… | …… | …… | …… | …… | …… | …… | 1 | 7天留存率 | 20200627 | …… | …… | …… | …… | …… | …… | …… | …… | …… | 2 | 7天环比 | 20200627 | 华东 | 上海 | …… | …… | …… | …… | …… | …… | …… | 大家可以看到,当我们创建这样的表的时候,就可以通过标红的条件来查询报表了。例如,我要查“7天环比”,就可以通过报表名称='7天环比'或者报表ID=2来查询。另一种方式则是键值对,具体设计可以参考下面的方式:
报表ID | 报表名称 | 报表日期 | 维度1 | 维度2 | 维度3 | 类别1 | 值1 | 类别2 | 值2 | 类别3 | 值3 | 类别4 | 值4 | 类别5 | 值5 | 类别6 | 值6 | 类别7 | 值7 | 类别8 | 值8 | 类别9 | 值9 | 类别10 | 值10 | 类别11 | 值12 | 类别12 | 值13 | 类别14 | 值14 | 1 | 报表1 | 20200627 | 华北 | 黑龙江 | 哈尔滨 | 星期一留存率 | …… | 星期一环比 | …… | 星期二留存率 | …… | 星期二环比 | …… | | | | | | | | | | | | | | | 星期天留存率 | …… | 星期天环比 | …… | 1 | 报表2 | 20200627 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 具体采用哪种方式,根据实际而定。第二种看起来比较直观,但在数据处理上,可能没有第一种方便。个人觉得,确实需要两个表融合的情况下,再考虑第二种方式。
当表设计完成后,就开始考虑存储过程的编写了。前面已经讲很多了。这里不打算展开讲解。只说一下和前面不太一样的地方。
我们知道,存储过程,在报表开发的过程中,无非就是各种插入,更新,删除等等。也许有循环、创建视图等情况。但万变不离其宗,依然以操作查询为主。
理论上,我们当然可以把所有报表的存储过程全部贴进来,例如【这里只给伪代码】:
- CREATE PROCEDURE [dbo].[sp_user_count] @min_date date=null
- AS
- BEGIN
- --定义9个日期变量
- declare @SQL varchar(500)
- declare @i int
复制代码 但这样做会导致一个问题,例如,我需要调整某个步骤时,存储过程就必须全部跑一次。也就是说,这样会产生强耦合现象。
如果步骤比较少,影响倒不是很大。如果步骤比较多,而且数据比较多的时候,对服务器的影响还是比较大的。所以我们应该考虑解耦。于是就有了下面这个写法:
- CREATE PROCEDURE [dbo].[sp_user_count] @min_date date=null,@start_step int=0,@end_step int=100
- AS
- BEGIN
- --定义9个日期变量
- declare @SQL varchar(500)
- declare @i int
- if @min_date is null
- set @min_date=dateadd(day,-8,GETDATE())
复制代码 这样写有什么好处呢?这样写的话,当我们修改了留存率算法的时候,想知道结果,又不想跑那么多存储过程的时候,就可以直接运行以下语句:
exec sp_user_count '2020-06-27',0,0
再如,如果想单独运行环比,则改为:
exec sp_user_count '2020-06-27',1,1
如果想运行前面这两个,也简单:
exec sp_user_count '2020-06-27',0,1
或者干脆把“0”去掉。即:exec sp_user_count '2020-06-27',,1
这样一来的话,任何连续范围都是可以通过后面两个参数来执行的。如果不是连续范围,则分成若干块一起执行即可。例如:
exec sp_user_count '2020-06-27',0,0
exec sp_user_count '2020-06-27',5,6
事实上,上面这种情况是最常见的。还是拿前面那个例子来说,例如,我想看看修改了留存率算法后的结果,第5、6步分别是将数据插入当前表、备份数据。那么就可以按上面这样写了。下面附上Sybase的一些写法截图。SQL server也是类似的,这里就不展开了:
这里是开头部分:
这里是结束部分:
相关文章:
浅谈数据库开发(一):关于宽表
浅谈数据库开发(二)——从宽表到存储过程(之一)
浅谈数据库开发(三)——从宽表到存储过程(之二)
浅谈数据库开发(四)——从宽表到存储过程(之三)
浅谈数据库开发(五)——从宽表到存储过程(之四)
浅谈数据库开发(六)——从宽表到存储过程(之五)
|
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有帐号?注册
x
评分
-
查看全部评分
|