2012年7月4日星期三

彩笔写网站

彩笔写网站

好吧,这是我的第一篇随笔。。。本人彩笔,求讨论,求指导,求改正,求不喷

先说一下这个浏览量统计吧,最简单最直接的实现:直接打开页面我就update数据库呗。。。好吧,如果浏览量稍许大怎么办捏,数据库会不会挂,会不会影响页面的打开速度呢,看来不咋靠谱

那么,我们就想到了,是不是可以把浏览量的数据放到内存中呢(反正我是这么想的),反正这玩意实时性也没多大意义。。。嗯,这样的话我就可以定时写入数据库了,貌似有点靠谱,好哒,不管这些了,先整一个再说

代码如下:

  1     /// <summary>  2     /// 需要统计的数据类型  3     /// </summary>  4     public enum StatisticsData  5     {  6         Person,  7         Event,  8         Place,  9         Object 10     } 11     /// <summary> 12     /// 需要统计的操作 13     /// </summary> 14     public enum StatisticsOperation 15     { 16         /// <summary> 17         /// 浏览 18         /// </summary> 19         View, 20         /// <summary> 21         /// 支持 22         /// </summary> 23         Support, 24         /// <summary> 25         /// 反对 26         /// </summary> 27         Against, 28         /// <summary> 29         /// 评论 30         /// </summary> 31         Talk 32     } 33     /// <summary> 34     /// 统计单元 35     /// </summary> 36     public class StatisticsUnit 37     { 38         public StatisticsData DataType; 39         public int ID; 40         public int Version;//版本号和ID可视为联合主键 41         public int ViewCount;//浏览增量 42         public int SupportCount;//支持数增量 43         public int AgainstCount;//反对数增量 44         public int TalkCount;//评论数增量 45  46         public bool OverMaxCount 47         { 48             get 49             { 50                 //读取配置,判断 51                 //如果超过单位时间内的最大增量,则返回true 52                 return true; 53             } 54         } 55  56         public void Count(StatisticsOperation operation) 57         { 58             switch (operation) 59             { 60                 case StatisticsOperation.View: 61                     ViewCount++; 62                     break; 63                 case StatisticsOperation.Support: 64                     SupportCount++; 65                     break; 66                 case StatisticsOperation.Against: 67                     AgainstCount++; 68                     break; 69                 case StatisticsOperation.Talk: 70                     TalkCount++; 71                     break; 72                 default: 73                     break; 74             } 75         } 76     } 77  78     /// <summary> 79     /// 内存中的统计数据集合 80     /// 这种工具式的类,如果要到处new的话,我感觉很恶心,所以使用static,然后用lock保证线程安全 81     /// 比如,我要开一瓶啤酒,我只需要找到瑞士军刀,使用里面的酒瓶起子就可以了,而不是new一个瑞士军刀,然后使用里面的起子 82     /// 不知道我的理解对不对,求讨论,求指导 83     /// </summary> 84     public static class StatisticsSet 85     { 86         private static List<StatisticsUnit> list = new List<StatisticsUnit>(); 87         private static List<StatisticsUnit> tmplist = new List<StatisticsUnit>(); 88         private static DateTime time = DateTime.UtcNow; 89         public delegate void DBOperation(ref List<StatisticsUnit> list); 90  91         /// <summary> 92         /// 当list中存在该记录,则自增统计数据,否则添加 93         /// </summary> 94         /// <param name="Unit"></param> 95         /// <param name="OperationType"></param> 96         public static void Append(StatisticsUnit Unit, StatisticsOperation OperationType) 97         { 98             lock (list) 99             {100                 //自增或添加101                 StatisticsUnit Query = list.Where(u => u.DataType == Unit.DataType && u.ID == Unit.ID && u.Version == Unit.Version).FirstOrDefault();102                 if (Query != null)103                     Query.Count(OperationType);104                 else105                     list.Add(Unit);106                 //检测是否已经达到更新数据库的条件并执行相关操作107                 if (Monitor.TryEnter(tmplist))108                 {109                     bool overmaxexist = list.Exists(unit => unit.OverMaxCount);110                     if (overmaxexist || time.AddMinutes(30/*配置文件:多长时间更新一次数据库*/) >= DateTime.UtcNow)111                     {112                         //使用委托和多线程创建无阻塞调用113                         DBOperation operation = new DBOperation(WriteDB);114                         //AsyncCallback callback = new AsyncCallback(CallBack);115                         operation.BeginInvoke(ref tmplist, null, null);116                     }117                 }118             }119         }120 121         /// <summary>122         /// 根据list生成SQL语句并更新数据库123         /// </summary>124         /// <param name="list"></param>125         private static void WriteDB(ref List<StatisticsUnit> list)126         {127             lock (tmplist)128             {129                 tmplist = list.OrderBy(unit => unit.DataType).ThenBy(unit => unit.ID).ToList();130                 list.Clear();131                 time = DateTime.UtcNow;132                 //根据list生成SQL语句并更新数据库133                 tmplist.Clear();134             }135         }136     }

好吧,其实还有几个问题,求完善,求讨论

既然需要统计的数据类型分为4种,那么要不要把list也分成4个呢,这样的话会不会减少lock的几率,执行的更快一点呢

求讨论,求完善,求指导,各种求。。。


TAG: