求一设计思想或者数据结构!(做过计数器的朋友应该能搞定!)

swazn_yj 2006-08-23 09:38:12
小弟作了个广告发布系统,统计广告点击量的时候遇到个问题比较棘手,请各位赐教!
点击量是按独立ip计数的,每独立ip每天点击数超过10次按10次计,所以要记录这个ip到第10次点击的时候的时间,它再点击就要比较这个时间过没过24小时,然后再重新计数。大体就是这么个意思。
我的表初步设计如下:
CREATE TABLE [Sw_Hits] (
[id] [int] IDENTITY (1, 1) NOT NULL ,
[AdID] [int] NULL ,
[CpID] [int] NULL ,
[HitTime] [smalldatetime] NULL CONSTRAINT [DF_Sw_Hits_HitTime] DEFAULT (getdate()),
[CusIP] [varchar] (50) COLLATE Chinese_PRC_CI_AS NULL ,--(客户ip)
[SerIP] [varchar] (50) COLLATE Chinese_PRC_CI_AS NULL ,
[SessionStart] [smalldatetime] NULL ,--(10次后的时间)
[Hits] [int] NULL CONSTRAINT [DF_Sw_Hits_Hits] DEFAULT (0),(总点击量)
[SessionHits] [int] NULL CONSTRAINT [DF_Sw_Hits_SessionHits] DEFAULT (0),(超过10次清0,update sessionstart,累加到总点击量)
CONSTRAINT [PK_Sw_Hits] PRIMARY KEY CLUSTERED
(
[id]
) ON [PRIMARY]
) ON [PRIMARY]
GO

就是来一个ip的访问,我先查询数据库有没有这个ip,没有就insert,有就查sessionstart是否为null,是就查sessionhits是否超过了10,超过就把它清0,sessionstart=getdate(),hits=hits+sessionhits,如果sessionstart不为null就比较时间是否超过24小时,是就重新计数。
这样的方法感觉判断比较麻烦,我一直也没写好,但是这样应该很节省数据库的记录数。
但是公司要点击数报表的话需要每小时、每天统计,以上的流程又要加上时间判断,每过一小时新增一条记录......想想头就大了!
还有个方法是来一条先count一下数据库里有多少条,少于10条就insert,大于10条就比较跟最后一条的时间差是否超过24小时,超过就继续insert,但是这样的话,日点击量如果超过1w独立ip,数据库的记录就超过10w条,我怕数据库顶不住。


各位大哥有没有很好解决这个统计问题的方案??


...全文
1603 56 打赏 收藏 转发到动态 举报
写回复
用AI写文章
56 条回复
切换为时间正序
请发表友善的回复…
发表回复
swazn_yj 2006-08-28
  • 打赏
  • 举报
回复
24小时跟一天其实没有什么区别,以天为单位的话,就是第一次点击的时候会统计的有点误差,比如23:50的时候我点了9次,到第二天了,仅此而已!
swazn_yj 2006-08-28
  • 打赏
  • 举报
回复
对!!
xdk 2006-08-28
  • 打赏
  • 举报
回复
taochunsong(老桃 http://www.laotao.cn(qq113352478注明CSDN))
是连续24小时,不是一天

--------------------------------------------------------
晕.这个限制超简单...datediff里改为小时判断不就行了吗?
taochunsong 2006-08-28
  • 打赏
  • 举报
回复
是连续24小时,不是一天
xdk 2006-08-28
  • 打赏
  • 举报
回复
如果你IP每天超1W,就有10W条记录,保留三天记录也就有30W...不算多.SQL足可以应付得来...但,优化一下,,,还要建索引...
xdk 2006-08-28
  • 打赏
  • 举报
回复
还有...取ASP要取MAC地址.只能写插件.下载到客户端的.还是不要用.net来写插件...

读MAC方法.

http://www.zqba.com/blog/article.asp?id=14

解决客户端插件的数字签名方法:
http://www.zqba.com/blog/article.asp?id=18

对WINXP+SP2的插件调用解决方法(我还没有加上去.呵呵,有空再加,或你有什么不懂留言给我)
http://www.zqba.com/blog/article.asp?id=20




PS.MAC地址作为判断,也是不准的...MAC地址也能改...不过.总比取IP来得准确多了.

xdk 2006-08-28
  • 打赏
  • 举报
回复
To:xdk(http://www.zqba.com/blog)
老兄,你的好想不是一个ip一天只能访问一次,而是iCountIP只加一次,iCount一直可以被刷新啊!
---------------------------------------
而是iCountIP是IP访问量,iCount是总访问量(不限IP),这样就总访问量与IP访问量都有了嘛.而且这是我们的广告系统要求.你按需求改一下就行了.


以下是清空IP的存储过程:

/*
存储过程:p_tb_Count_det_Clear
功能:清空三天前的IP详细

*/
CREATE PROCEDURE p_tb_Count_det_Clear

AS
DELETE FROM tb_Count_det WHERE Datediff(d,dtTime,GetDate())>3
GO




以下是调度(你最好自己建,在管理--SQL SERVER代理--作业)

— 2006-8-28/9:49 上生成的脚本
— 由: USER-9B09BE8C4A\ZQFrog
— 服务器: (local)

BEGIN TRANSACTION
DECLARE @JobID BINARY(16)
DECLARE @ReturnCode INT
SELECT @ReturnCode = 0
IF (SELECT COUNT(*) FROM msdb.dbo.syscategories WHERE name = N'[Uncategorized (Local)]') < 1
EXECUTE msdb.dbo.sp_add_category @name = N'[Uncategorized (Local)]'

— 删除同名的警报(如果有的话)。
SELECT @JobID = job_id
FROM msdb.dbo.sysjobs
WHERE (name = N'Clear_Countdet')
IF (@JobID IS NOT NULL)
BEGIN
-- 检查此作业是否为多重服务器作业
IF (EXISTS (SELECT *
FROM msdb.dbo.sysjobservers
WHERE (job_id = @JobID) AND (server_id <> 0)))
BEGIN
-- 已经存在,因而终止脚本
RAISERROR (N'无法导入作业“Clear_Countdet”,因为已经有相同名称的多重服务器作业。', 16, 1)
GOTO QuitWithRollback
END
ELSE
-- 删除[本地]作业
EXECUTE msdb.dbo.sp_delete_job @job_name = N'Clear_Countdet'
SELECT @JobID = NULL
END

BEGIN

— 添加作业
EXECUTE @ReturnCode = msdb.dbo.sp_add_job @job_id = @JobID OUTPUT , @job_name = N'Clear_Countdet', @owner_login_name = N'USER-9B09BE8C4A\ZQFrog', @description = N'清空IP访问详细', @category_name = N'[Uncategorized (Local)]', @enabled = 1, @notify_level_email = 0, @notify_level_page = 0, @notify_level_netsend = 0, @notify_level_eventlog = 2, @delete_level= 0
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback

— 添加作业步骤
EXECUTE @ReturnCode = msdb.dbo.sp_add_jobstep @job_id = @JobID, @step_id = 1, @step_name = N'Clear', @command = N'EXECUTE p_tb_Count_det_Clear', @database_name = N'ads', @server = N'', @database_user_name = N'', @subsystem = N'TSQL', @cmdexec_success_code = 0, @flags = 0, @retry_attempts = 0, @retry_interval = 1, @output_file_name = N'', @on_success_step_id = 0, @on_success_action = 1, @on_fail_step_id = 0, @on_fail_action = 2
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
EXECUTE @ReturnCode = msdb.dbo.sp_update_job @job_id = @JobID, @start_step_id = 1

IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback

— 添加作业调度
EXECUTE @ReturnCode = msdb.dbo.sp_add_jobschedule @job_id = @JobID, @name = N'Clear', @enabled = 1, @freq_type = 4, @active_start_date = 20060828, @active_start_time = 0, @freq_interval = 1, @freq_subday_type = 1, @freq_subday_interval = 0, @freq_relative_interval = 0, @freq_recurrence_factor = 0, @active_end_date = 99991231, @active_end_time = 235959
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback

— 添加目标服务器
EXECUTE @ReturnCode = msdb.dbo.sp_add_jobserver @job_id = @JobID, @server_name = N'(local)'
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback

END
COMMIT TRANSACTION
GOTO EndSave
QuitWithRollback:
IF (@@TRANCOUNT > 0) ROLLBACK TRANSACTION
EndSave:



swazn_yj 2006-08-28
  • 打赏
  • 举报
回复
SET QUOTED_IDENTIFIER OFF
GO
SET ANSI_NULLS ON
GO

--execute p_tb_Count_Manager @cAct='add',@iADID=1,@cIP='127.0.0.1',@cFrom='http://dvd.txwnet.com/view.asp?pid=1255'
CREATE PROCEDURE p_tb_Count_Manager
@cAct varchar(6),--操作指令
@iADID int=0,--广告ID
@cIP varchar(15),--访问IP
@cFrom varchar(100)--来源


AS

DECLARE @iRet int
--添加
IF @cAct='add'
BEGIN

--判断该IP是否访问了这一广告,否,IP访问+1,是,IP访问不变
IF EXISTS(SELECT tCount FROM tb_Count_det WHERE iADID=@iADID AND cIP=@cIP AND (Datediff(d,dtTime,GetDate())=0))
BEGIN
--当天访问数加1
--这里加入判断tCount是否=10,是,就置
SELECT @iRet=tCount FROM tb_Count_det WHERE iADID=@iADID AND cIP=@cIP AND (Datediff(d,dtTime,GetDate())=0)
IF @iRet<10
UPDATE tb_Count SET iCount=iCount+1 WHERE iADID=@iADID AND (Datediff(d,dtTime,GetDate())=0)
UPDATE tb_Count_det SET tCount=tCount+1,dtTime=GetDate() WHERE iADID=@iADID AND cIP=@cIP AND (Datediff(d,dtTime,GetDate())=0)

IF @@Error<>0 OR @@RowCount<=0
GOTO Error
ELSE
RETURN 0
END
ELSE
BEGIN
--插入IP访问详细
INSERT INTO tb_Count_det(iADID,cIP,cFrom,tCount) VALUES(@iADID,@cIP,@cFrom,1)
--当天该广告已有访问,更新
IF EXISTS(SELECT iID FROM tb_Count WHERE iADID=@iADID AND (Datediff(d,dtTime,GetDate())=0))
UPDATE tb_Count SET iCount=iCount+1,iCountIP=iCountIP+1 WHERE iADID=@iADID AND (Datediff(d,dtTime,GetDate())=0)
--当天该广告未访问,插入
ELSE
INSERT INTO tb_Count(iADID,iCount,iCountIP) VALUES(@iADID,1,1)
RETURN 2
END

END

--详细资料
ELSE IF @cAct='detail'
SELECT * FROM tb_Count WHERE iADID=@iADID


Success:
RETURN 0
Error:
RETURN 1

GO
SET QUOTED_IDENTIFIER OFF
GO
SET ANSI_NULLS ON
GO

这个是我改造你那个而成的,初步测试达到了效果。只是不知道怎么写多一个调度...每天执行一次.删除三天以前的IP记录
swazn_yj 2006-08-28
  • 打赏
  • 举报
回复
To:xdk(http://www.zqba.com/blog)
老兄,你的好想不是一个ip一天只能访问一次,而是iCountIP只加一次,iCount一直可以被刷新啊!
swsky 2006-08-28
  • 打赏
  • 举报
回复
xdk(http://www.zqba.com/blog)
厉害啊!PFPF!
chenweicai 2006-08-27
  • 打赏
  • 举报
回复
网赚,让我们梦想成真!
访问http://chenweicai.nud8.com
世界已进入了一个新时代,财富的概念已经发生了深刻的变化。财富不再以占有土地、矿产、工厂、劳力等有形资产的多少来衡量;而是以拥有信息、知识、智慧、比特等无形资源的多少来衡量了。索罗斯在3个月内赚12亿美金,比尔.盖茨在短短几年内成为世界首富,扬致远、张朝阳、丁磊从一无所有到亿万富翁只用了2年时间、英国的阿塔拉从穷学生到亿万富翁的历程只有5个月,而李泽楷一夜之间赚了他父亲李嘉诚一辈子的钱......这些奇迹,用传统思维是无法想象的“在网络时代,世界500强与普通人站在同一条起跑线上”。你相信这一点,明日的富翁或许就是你!

第一批下海经商的人----富了,第一批买原始股的人----富了,第一批买地皮的人----富了。

他们富了,因为他们敢于在大多数人还在犹豫不决的时候就作出了实际行动。他们先行一步,便抢得了商机,占领了市场。今天,网上赚钱也是新生事物,在很多人还不了解的时候,你开始行动,你便抢得了商机,占领了市场的制高点。早一天加入,你就早一天获得成功!

目前在中国,MLM还是初露端倪,这就和91年股票市场刚刚进入中国的时候相似,当时也有好多人不相信股票能挣钱。但是当第一批富翁从股票市场里造就出来的时候,当初没有投资的人又都追悔莫及。随着加入WTO后和外界思维的互通有无,在不久以后MLM一定会风靡全国!

在中国网上能赚钱,绝大多数的人都不敢相信,因为刚起步。话又说回来,只要有10%的人理解就足够啦,你要知道,有钱人就在10%里面,不在90%,90%的人注定永远是平民百姓。你是属于
90%的人呢?还是想成为10%中的一员!

成功只青睐于有胆识的人!
难道,一定要等到全国人民都开始赚钱的时候,你才决定行动么?


网络,带给我们的不只是聊天和游戏!它蕴藏着实现梦想的无限可能!访问
http://chenweicai.nud8.com
疑难问题解答请进:http://www.nud8.com/mlm/wenti.php?mid=chenweicai
请注册后的会员们一定要联系我 QQ:654923398
E-mail:wwwxueyou@163.com
  
注意:注册的时候一定要填自己的真实姓名、真实地址、属于自己的真实的电子邮箱,否则收
不到钱的话,不要来怪我哦!注册完之后,24小时之内你的邮箱将收到一封确认信。

也许,有人说这是骗 人的,如果我真是骗 子的话,为什么还花这么多的时间来宣传呢?难道我上网不用花钱吗?难道我不累吗?
成功只青睐于有胆识的人!
  
有兴趣加入的朋友,请把这个贴子复制到你的电脑里去,因为论坛版主删这种广告贴删得比较快,一会就不见了。
kingtoo010 2006-08-27
  • 打赏
  • 举报
回复
帮顶..接分...
------------------------------------------------------------------------------------
100M.Net空间+50M企业邮局=60元/年
100M.Net空间+国际顶级域名=100元/年
国际顶级域名.com.net.cn=50元/年
本站申请域名可绑定免费10M Asp.Net空间
1000M.Net空间 + 100M MsSql数据库 + 1000M企业邮局 + 顶级域名=600元/年
数据库 企业邮局 网站推广 整机租用 美国空间 网站建设 均有售
还有很多优惠套餐提供给各个用户层.
有意者可联系电话:021-64802212 传真:021-64802212
咨询信箱:info@kingtoo.com 咨询OICQ:68311305,379620139 81778640
soft_2008 2006-08-26
  • 打赏
  • 举报
回复
- -
xdk 2006-08-26
  • 打赏
  • 举报
回复
tb_Count_det数据量可以以后会蛮大的.可以写多一个调度...每天执行一次.删除三天以前的IP记录...这样速度蛮快的.而且,因为在tb_Count里已经记录了这些访问量,tb_Count_det这些记录可以不要也行的...
pcworld 2006-08-26
  • 打赏
  • 举报
回复
答案有了
xdk 2006-08-26
  • 打赏
  • 举报
回复
作统计的分两个表.一个是统计数:tb_Count,一个是统计详细(记IP之用):tb_Count_det
结构说明:

tb_Count
[iID] [int] IDENTITY (1, 1) NOT NULL , --自动编号
[iADID] [int] NULL , --广告ID(关联广告表)
[iCount] [int] NULL , --访问量(总访问,页面展示次数)
[iCountIP] [int] NULL , --IP访问量(单一IP访问量)
[iCountClick] [int] NULL , --广告点击(这个你可以不需要)
[dtTime] [datetime] NULL --统计时间(当天)
tb_Count_det
[iID] [int] IDENTITY (1, 1) NOT NULL , --自动编号
[iADID] [int] NULL , --广告ID(关联广告表)
[cIP] [varchar] (15) COLLATE Chinese_PRC_CI_AS NULL , --用户IP
[cFrom] [varchar] (100) COLLATE Chinese_PRC_CI_AS NULL , --来源
[dtTime] [datetime] NULL --访问时间
xdk 2006-08-26
  • 打赏
  • 举报
回复
偶做了一个的.广告统计的,不过是一天一个IP算一次...

表:
if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[tb_Count]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
drop table [dbo].[tb_Count]
GO

if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[tb_Count_det]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
drop table [dbo].[tb_Count_det]
GO

CREATE TABLE [dbo].[tb_Count] (
[iID] [int] IDENTITY (1, 1) NOT NULL ,
[iADID] [int] NULL ,
[iCount] [int] NULL ,
[iCountIP] [int] NULL ,
[iCountClick] [int] NULL ,
[dtTime] [datetime] NULL
) ON [PRIMARY]
GO

CREATE TABLE [dbo].[tb_Count_det] (
[iID] [int] IDENTITY (1, 1) NOT NULL ,
[iADID] [int] NULL ,
[cIP] [varchar] (15) COLLATE Chinese_PRC_CI_AS NULL ,
[cFrom] [varchar] (100) COLLATE Chinese_PRC_CI_AS NULL ,
[dtTime] [datetime] NULL
) ON [PRIMARY]
GO

ALTER TABLE [dbo].[tb_Count] WITH NOCHECK ADD
CONSTRAINT [DF_tb_Count_iCountClick] DEFAULT (0) FOR [iCountClick],
CONSTRAINT [DF_tb_count_dtdatetime] DEFAULT (getdate()) FOR [dtTime]
GO

ALTER TABLE [dbo].[tb_Count_det] WITH NOCHECK ADD
CONSTRAINT [DF_tb_Count_det_dtTime_1] DEFAULT (getdate()) FOR [dtTime]
GO


用存储过程+ASP实现.
以下是作统计的存储过程...如果你要改为十条...加判断就行了.

/*
存储过程:p_tb_Count_Manager
功能:广告访问量管理(添加,修改,详细,删除)
*/
CREATE PROCEDURE p_tb_Count_Manager
@cAct varchar(6), --操作指令
@iADID int=0, --广告ID
@cIP varchar(15), --访问IP
@cFrom varchar(100) --来源


AS
DECLARE @GetDate varchar(20)
DECLARE @iRet int
DECLARE @cAction varchar(500)
SET @GetDate=GetDate()

--添加
IF @cAct='add'
BEGIN

--判断该IP是否访问了这一广告,否,IP访问+1,是,IP访问不变
IF EXISTS(SELECT iID FROM tb_Count_det WHERE iADID=@iADID AND cIP=@cIP AND (Datediff(d,dtTime,GetDate())=0))
BEGIN
--当天访问数加1
UPDATE tb_Count SET iCount=iCount+1 WHERE iADID=@iADID AND (Datediff(d,dtTime,GetDate())=0)
IF @@Error<>0 OR @@RowCount<=0
GOTO Error
ELSE
RETURN 0
END
ELSE
BEGIN
--插入IP访问详细
INSERT INTO tb_Count_det(iADID,cIP,cFrom) VALUES(@iADID,@cIP,@cFrom)
--当天该广告已有访问,更新
IF EXISTS(SELECT iID FROM tb_Count WHERE iADID=@iADID AND (Datediff(d,dtTime,GetDate())=0))
UPDATE tb_Count SET iCount=iCount+1,iCountIP=iCountIP+1 WHERE iADID=@iADID AND (Datediff(d,dtTime,GetDate())=0)
--当天该广告未访问,插入
ELSE
INSERT INTO tb_Count(iADID,iCount,iCountIP) VALUES(@iADID,1,1)
RETURN 2
END

END

--详细资料
ELSE IF @cAct='detail'
SELECT * FROM tb_Count WHERE iADID=@iADID


Success:
RETURN 0
Error:
RETURN 1
GO

xdk 2006-08-26
  • 打赏
  • 举报
回复
插入前Select一次.
kingtoo009 2006-08-26
  • 打赏
  • 举报
回复
帮顶..接分...
------------------------------------------------------------------------------------
100M.Net空间+50M企业邮局=60元/年
100M.Net空间+国际顶级域名=100元/年
国际顶级域名.com.net.cn=50元/年
本站申请域名可绑定免费10M Asp.Net空间
1000M.Net空间 + 100M MsSql数据库 + 1000M企业邮局 + 顶级域名=600元/年
数据库 企业邮局 网站推广 整机租用 美国空间 网站建设 均有售
还有很多优惠套餐提供给各个用户层.
有意者可联系电话:021-64802212 传真:021-64802212
咨询信箱:info@kingtoo.com 咨询OICQ:68311305,379620139 81778640
webDreamsinger 2006-08-26
  • 打赏
  • 举报
回复
所有点击记录都应该详细记录下来,只有把点击记录全记下来之后,才好去分析哪些是无效的点击。
如果你想得到更加精通的统计,特别是涉及费用、账务方面的东西,一切就应该做得有记录,可查询。不然你很难对统计作出可靠的解释,现在百度竞价很多客户都指其暗箱操作,因为客户无法查询到详细的访问记录。当然这样做可能会数据库很大。


对于判断是否来自一台机器的判断,常规上有IP判断,cookies等(目前拒绝cookies的客户端并不多),你可以综合一下:
ip+cookies+浏览器版本+屏幕大小+操作系统+进入网站的入口+链接来源+所浏览的页面+点击发生与进入页面的时间间隔等。


加载更多回复(36)

28,390

社区成员

发帖
与我相关
我的任务
社区描述
ASP即Active Server Pages,是Microsoft公司开发的服务器端脚本环境。
社区管理员
  • ASP
  • 无·法
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧