ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

重构经历(一)

2019-07-29 23:08:34  阅读:204  来源: 互联网

标签:Status 重构 WebSite 经历 Campaigns time WebSiteID now


原文链接:http://www.cnblogs.com/psunny/archive/2010/09/19/1831135.html

 

一、基本需求

在当前的项目中,很多用户都有订阅论坛中不同的类别,程序需要根据用户订阅的触发时间来向用户发送邮件。

在这里涉及到几个表。

WebSites包含论坛的URL, LogoURL, Status, Description等信息
Campaigns 和WebSite相关,一般情况下一个WebSite只对应一个Campaign,它也包含一个Status
Subscribers 订阅用户,包含Email, FirstName, LastName等订户信息
Subscriptions 订阅用户所订阅的类别,包含类别,类别所在的论坛,订阅时间,接收邮件的具体时间(时分秒),接收周期(WeekInterval varchar(7) 值可能是0123456这个字符串中的任意组合,如023表示用户将在周日,周三,周四收到邮件)。

实际上Subscribers和Subscriptions也都包含Status字段,有些信息是不能够通过邮件来发送的或者用户退订了。

 

二、实现过程

之前由于不太明确需求,我把业务逻辑的主次给颠倒了,我是根据当前时间去查询Subscriptions表,看有哪些订阅者,这些订阅者又分别属于哪个WebSite,这是一个从下往上找的过程。

Subscriptions –> Subscribers –> Campaigns / WebSites

但是后来醒悟过来,如果WebSite的Status为"D"(Disabled),那么这个站点下的所有用户将在一段时间内收不到邮件,知道Status转变为"A"(Active)。

现在转变过来了,则应当是:WebSites –> Campaigns –> Subscribers –> Subscriptions。

之前的WebService部分和存储过程在现在这种情况下都要改动。

 

三、重构过程

(1) 第一次重构

之前为了测试方便,把方法分的很开,可笑的对Campaign写了3个WebMethod,GetCampaign()、IsCampaignExists()、CreateCampaign(),甚至每个方法都会调用一个简短的StoredProcedure。其实我的目的仅仅是为了获取一个Campaign而已,至于IsCampaignExists()、CreateCampaign()这根本和功能无关紧要。于是我考虑三个存储过程合而为一,三个WebMethod也合而为一。改成GetCampaign()

于是,我改了方法,改了存储过程,自以为代码量减少了,业务逻辑也符合了,但是却忽略了Campaign和WebSite的Status

(2)第二次重构

由于加入了Status,所以至上而下的找,有缝缝补补,更为GetActiveCampaign()

(3)第三次重构

到现在我才真正明白这个需求,我其实是为了拿取当前时间下,状态处于Active,并且有订阅用户将会接收到邮件的WebSite,其他的Campaign并不是最顶层的。

而且第二次重构的结果导致我只能拿取一条数据,这样则会造成多次访问数据库,我还是索性的一次拿光吧。最终只有GetActiveWebSites()

四、SQL重构

(1)第一次重构

获取当前有订户需要接收邮件的WebSite

create proc [dbo].[SP_GetCurrentWebsites]
(
@weekday int
)
as
declare @now datetime
declare @now_time time

set @now = GETDATE()
set @now_time = @now
select distinct Subscribers.WebSiteID from Subscribers 
inner join Subscriptions
on Subscribers.ID = Subscriptions.SubscriberID
where  WeekDays = @weekday
and StartTime < @now_time

GO

获取处于激活状态的WebSite

create proc [dbo].[SP_GetActiveCampaigns]
as
select Campaigns.* from Campaigns 
inner join WebSites
on Campaigns.WebSiteID = WebSites.ID and WebSites.Status = 'A' and Campaigns.Status = 'A'
GO

然后获取最终的WebSite的方法我是放到程序里进行处理的,写好了,发现这让我感觉很别扭,总觉得多余,为了获取WebSite我竟然花了3个步骤。

(2)第二次重构

简化为一个存储过程,一个WebMethod调用。

--获取WebSite
create proc SP_GetActiveWebSites
(
@weekday varchar(1)
)
as
declare @now datetime
declare @now_time time
set @now = GETDATE()
set @now_time = @now
select w.ID from 
(
select distinct s1.WebSiteID from Subscribers s1
inner join Subscriptions s2 on s1.ID = s2.SubscriberID
where  CHARINDEX(@weekday,s2.WeekDays) > 0
and StartTime < @now_time
) t
inner join WebSites w on t.WebSiteID = w.ID
inner join Campaigns c on c.WebSiteID = w.ID
where w.Status = 'A' and c.Status = 'A'
go

--执行查询
declare @start datetime
set @start = GETDATE()
exec SP_GetActiveWebSites '1'
select DATEDIFF(MILLISECOND, @start, GETDATE()) as QueryTime

为了获取几条数据,这个查询花了4000多毫秒,由于Subscriptions和Subscribers表数据量较大,这几个表都inner join会花费很多时间。

(3)第三次重构

alter proc SP_GetActiveWebSites
(
@weekday varchar(1)
)
as
declare @now datetime
declare @now_time time

set @now = GETDATE()
set @now_time = @now
--临时表1
create table #Temp1(ID bigint, WebSiteID bigint)
insert into #Temp1
select Campaigns.ID, Campaigns.WebSiteID from (Campaigns 
inner join WebSites
on Campaigns.WebSiteID = WebSites.ID and WebSites.Status = 'A' and Campaigns.Status = 'A' )
--临时表2
create table #Temp2(WebSiteID bigint)
insert into #Temp2 
select distinct s1.WebSiteID from Subscribers s1
inner join Subscriptions s2
on s1.ID = s2.SubscriberID
where  WeekDays = @weekday
and StartTime < @now_time

--临时表1,表二联合查询
select t1.ID, t1.WebSiteID from #Temp1 t1
inner join #Temp2 t2 on t1.WebSiteID = t2.WebSiteID 
go

--执行查询
declare @start datetime
set @start = GETDATE()
exec SP_GetActiveWebSites '1'
select DATEDIFF(MS,@start,GETDATE())
最终这个查询只需要500毫秒左右,重构完成。

转载于:https://www.cnblogs.com/psunny/archive/2010/09/19/1831135.html

标签:Status,重构,WebSite,经历,Campaigns,time,WebSiteID,now
来源: https://blog.csdn.net/weixin_30509393/article/details/97688984

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有