讨论一个比较有意思的业务需求
业务需求描述:
有一个用户登录表,用户每次登陆时,就会向这个表中插入一条数据,这个表记录了用户的用户ID和登录时间,表的数据量有几千万,
现在需要求出从今天开始算,用户持续登录的时间(也就是用户今天登陆了,昨天也登陆了,但是前天没有登录,那用户的持续登录时间就
是一天)。
分析:
看似蛮简单的一需求,在数据库里面实际操作起来不是那么简单的,并非一个简单的Select能够搞定的,从业务的描述我们起码可以得到如下
的分析结论:
1. 业务需要统计这样的数据,应该并不需要实时的数据,所以我们可以获取某个时间的快照数据来做计算;
2. 表数据量比较大,如果直接在这个表上操作,势必会对产品的使用造成影响(因为每个用户登录时,都需要再往里面插数据的);
3. 需要统计每个用户的持续登录时间,那意味着如果没有持续登录时间的用户就是不需要的用户,这里面应该可以筛选掉一大批用户;
4. 每个用户都需要做统计计算,这个肯定是一个循环计算的过程,我们最好前期能过滤掉一部分用户,那后面的统计计算无疑可以节省很多的时间;
5. 用户持续登录,一般时间不可能很长(很少有人天天去登陆一个网站,持续100天的吧),意味着我们可以用持续天数来做为循环条件,
而不必以用户来作为循环条件(用户做循环条件的话,循环次数应该会比较大);
6. 大数据量做统计,而且是定位到每个用户的,性能是必须要重点考虑的因素;
造测试数据:
测试数据其实有一个比较难的要求是能够尽量的接近真实数据,这样的测试效果才是最好的;我们预计造一个2千5百万的表,造几十万的用户,然后随机
的生成登陆时间,但是要求登录时间尽量能贴合真实的情况;
我们先创建测试表(其实最好是分区表):
--Create Test Tablecreate table dbo.UserLoginInfo( userid int ,logintime datetime ,CONSTRAINT [PK_UserInfo] PRIMARY KEY CLUSTERED ( userid ASC ,logintime ASC )WITH ( PAD_INDEX = OFF ,STATISTICS_NORECOMPUTE = OFF ,IGNORE_DUP_KEY = OFF ,ALLOW_ROW_LOCKS = ON ,ALLOW_PAGE_LOCKS = ON ,FILLFACTOR = 90 ) ON [PRIMARY] ) ON [PRIMARY]--DST Tablecreate table dbo.DST_UserLoginInfo( userid int ,logindate varchar(10) ,ContinueDays smallint ,IsOver bit ,CONSTRAINT [PK_UserLoginInfo] PRIMARY KEY CLUSTERED ( userid ASC ,logindate ASC )WITH ( PAD_INDEX = OFF ,STATISTICS_NORECOMPUTE = OFF ,IGNORE_DUP_KEY = OFF ,ALLOW_ROW_LOCKS = ON ,ALLOW_PAGE_LOCKS = ON ,FILLFACTOR = 90 ) ON [PRIMARY] ) ON [PRIMARY]
说明:我们创建了两个表,一个是模拟真实的用户登录数据的表,另外一个是我们准备做数据统计的表;
我们按时间由远到近,分几个批次来生成测试数据:
/*造二千五百万用户登录记录的过程*/--第一批次set nocount ongo--1000*5000=500Wdeclare @u_count intset @u_count=0--1000while @u_count1000begindeclare @userid int,@count intset @userid= rand()*100000set @count=0--5000while @count5000begininsert into dbo.UserLoginInfo(userid,logintime)--4
原创力文档

文档评论(0)