Xfce下ZendStudio的报错处理

4月 9th, 2010 | Posted by | Filed under 操作系统

为了轻量,我的Gentoo Linux用的Xfce桌面系统,一切都还不错,今天装ZendStudio遇到了些问题,记下。

安装的时候都很正常,解压下载的压缩包得到.bin文件,然后安装,也没有错,但是一启动就挂了。
查看了/home/plx/Zend/workspace/DefaultWorkspace7/.metadata/.log 发现如下异常:

!MESSAGE Application error
!STACK 1
org.eclipse.swt.SWTError: XPCOM error -2147467262
 at org.eclipse.swt.browser.Mozilla.error(Mozilla.java:1688)
 at org.eclipse.swt.browser.Mozilla.setText(Mozilla.java:1911)
 at org.eclipse.swt.browser.Browser.setText(Browser.java:750)
 at org.eclipse.ui.internal.intro.impl.presentations.BrowserIntroPartImplementation.generateContentForPage(BrowserIntroPartImplementation.java:363)
 at org.eclipse.ui.internal.intro.impl.presentations.BrowserIntroPartImplementation.dynamicStandbyStateChanged(BrowserIntroPartImplementation.java:577)
 at org.eclipse.ui.internal.intro.impl.presentations.BrowserIntroPartImplementation.doStandbyStateChanged(BrowserIntroPartImplementation.java:784)
 at org.eclipse.ui.internal.intro.impl.model.AbstractIntroPartImplementation.standbyStateChanged(AbstractIntroPartImplementation.java:249)
 at org.eclipse.ui.internal.intro.impl.model.IntroPartPresentation.standbyStateChanged(IntroPartPresentation.java:443)
 at org.eclipse.ui.intro.config.CustomizableIntroPart.standbyStateChanged(CustomizableIntroPart.java:266)
 at org.eclipse.ui.internal.ViewIntroAdapterPart$2.run(ViewIntroAdapterPart.java:74)
 at org.eclipse.swt.custom.BusyIndicator.showWhile(BusyIndicator.java:70)
 at org.eclipse.ui.internal.ViewIntroAdapterPart.setStandby(ViewIntroAdapterPart.java:70)
 at org.eclipse.ui.internal.ViewIntroAdapterPart$1.propertyChanged(ViewIntroAdapterPart.java:55)
 at org.eclipse.ui.internal.WorkbenchPartReference.fireInternalPropertyChange(WorkbenchPartReference.java:375)
 at org.eclipse.ui.internal.WorkbenchPartReference.fireZoomChange(WorkbenchPartReference.java:540)
 at org.eclipse.ui.internal.PartPane.setZoomed(PartPane.java:356)
 at org.eclipse.ui.internal.PartStack.setZoomed(PartStack.java:1526)
 at org.eclipse.ui.internal.PartSashContainer.zoomIn(PartSashContainer.java:884)
 at org.eclipse.ui.internal.PartSashContainer.childRequestZoomIn(PartSashContainer.java:905)
 at org.eclipse.ui.internal.LayoutPart.requestZoomIn(LayoutPart.java:354)
 at org.eclipse.ui.internal.PartStack.setState(PartStack.java:1501)
 at org.eclipse.ui.internal.WorkbenchPage.setState(WorkbenchPage.java:3872)
 at org.eclipse.ui.internal.WorkbenchPage.toggleZoom(WorkbenchPage.java:3944)
 at org.eclipse.ui.internal.WorkbenchIntroManager.setIntroStandby(WorkbenchIntroManager.java:201)
 at org.eclipse.ui.internal.WorkbenchIntroManager.showIntro(WorkbenchIntroManager.java:136)
 at org.eclipse.ui.application.WorkbenchWindowAdvisor.openIntro(WorkbenchWindowAdvisor.java:173)
 at org.eclipse.ui.internal.ide.application.IDEWorkbenchWindowAdvisor.openIntro(IDEWorkbenchWindowAdvisor.java:458)
 at org.eclipse.ui.internal.WorkbenchWindow.open(WorkbenchWindow.java:777)
 at org.eclipse.ui.internal.Workbench$22.runWithException(Workbench.java:1041)
 at org.eclipse.ui.internal.StartupThreading$StartupRunnable.run(StartupThreading.java:31)
 at org.eclipse.swt.widgets.RunnableLock.run(RunnableLock.java:35)
 at org.eclipse.swt.widgets.Synchronizer.runAsyncMessages(Synchronizer.java:133)
 at org.eclipse.swt.widgets.Display.runAsyncMessages(Display.java:3378)
 at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3036)
 at org.eclipse.ui.application.WorkbenchAdvisor.openWindows(WorkbenchAdvisor.java:803)
 at org.eclipse.ui.internal.Workbench$27.runWithException(Workbench.java:1361)
 at org.eclipse.ui.internal.StartupThreading$StartupRunnable.run(StartupThreading.java:31)
 at org.eclipse.swt.widgets.RunnableLock.run(RunnableLock.java:35)
 at org.eclipse.swt.widgets.Synchronizer.runAsyncMessages(Synchronizer.java:133)
 at org.eclipse.swt.widgets.Display.runAsyncMessages(Display.java:3378)
 at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3036)
 at org.eclipse.ui.internal.Workbench.runUI(Workbench.java:2293)
 at org.eclipse.ui.internal.Workbench.access$4(Workbench.java:2198)
 at org.eclipse.ui.internal.Workbench$5.run(Workbench.java:493)
 at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:288)
 at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:488)
 at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:149)
 at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:113)
 at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:193)
 at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:110)
 at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:79)
 at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:370)
 at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:179)
 at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
 at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
 at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
 at java.lang.reflect.Method.invoke(Method.java:597)
 at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:549)
 at org.eclipse.equinox.launcher.Main.basicRun(Main.java:504)
 at org.eclipse.equinox.launcher.Main.run(Main.java:1236)
 at org.eclipse.equinox.launcher.Main.main(Main.java:1212)

我以为是我没装JRE,但是安装目录下有JRE,Zend应该是调用自带的。
Google之,有人说删除xulrunner,我这依赖xulrunner的软件太多,不可能删。

发现有人说是少了个参数,
-Dorg.eclipse.swt.browser.XULRunnerPath=
这个java系统参数应该指定一个目录,但是这里可以任意写或者空着。
在添加该行后,重新启动ZendStudio,然后就可以把该行删除,以后再启动都不会报错了。
同理,因为ZendStudio基于Eclipse,所以Eclipse也适用。

标签: , , ,

每周推特 2010-04-04

4月 4th, 2010 | Posted by | Filed under 生活轨迹
  • Gentoo在X200的所有问题都解决了,内核驱动终于摸清楚了 #
  • 对运维的理解:预见风险,解决风险。 #
  • @asword2000 所以说遇见风险,然后规避风险。解决风险属于亡羊补牢,但也必须留这一手。 #
  • 对于NoSQL的狂热,自己做个东西强行用下NoSQL试试就知道了。并非任何场景都合适,简单数据结构,简单查询是可以的,但是想要分组、做一些聚合操作,需要安全的持久化策略,自己写代码实现吧,恐怕写的代码不比SQL数据库强。 #
  • 今天年会的照片会发出来不? #
  • 技吞山河,服甲天下。这也可以理解为一种做技术的胸襟。 #
  • 今天最大的收获是知道大牛们在做什么,怎么做。牛人不是用来模仿,但要学习。减少无意义的加班,把加班时间用到更有意义的事情上。 #
  • RT @yanzisky1989: 考完计算机= =貌似不难,希望能PASS {这全靠我灵魂附体} #
  • 排练时很不爽,感觉浪费时间,但是演完后又觉得有些空虚,有点习惯套个箱子一堆人一边排练一边扯淡,一边笑一边练。 #
  • RT @nzinfo: RT @hengdm: RT: 永远不要嫌弃父母学不会电脑,因为你不会知道在小的时候他们是如何不厌其烦地教你认字 #
  • 软件考古学,这个有意思 #
  • 团队里有几个技术狂人一起扯淡是非常幸运的事情 #
  • 如果一个软件的参数有最好的设置,那么这个设计本身就有问题,既然有适应任何场景的最佳设置,为什么还要把设置开放而不固化到程序内部。 #
  • 今天忙的天昏地暗,一点空闲时间都没有,都安排到通宵了…… #
  • 数据验证还没完,悲剧……先回家等待…… #
  • 终于搞完了,准备回家。查了银行卡,依然米有工资……继续接项目…… #
  • 累的没力气洗澡了,直接睡觉。 #
  • 被拉起来订正数据,开发人员的需求千奇百怪 #
  • 花费3天时间的迁移进入尾声,原本计划一晚完成的迁移,墨菲定理一次次验证,要相信RP是不可靠的 #
  • 迁移彻底完成。发现一个疑似MySQL的Bug,不影响应用,但是会错报复制延时,给mysql报告下这个Bug。 #
  • 总得来说,这次迁移收获很多,很难得的经验 #
  • @fire9 5.1.40,不过我觉得这可能不是一个版本的问题。如果两台库都开了log-slave-updates,一开始是M-S状态,然后切换为M-M状态,并且切的时候M没有停止服务,就可能带来误报复制延时。 in reply to fire9 #
  • @fire9 尽管从数据来看,近乎实时双向同步了,两边测试写也能相互复制,但是show slave status里面复制延时还是不断的增加。关掉其中一个log-slave-updates,或者先停止复制,重新change master,都可以修正。 in reply to fire9 #
  • SET GLOBAL sql_slave_skip_counter = N这个语句来跳过出错的复制,在迫不得已的情况下挺好用 #
  • 截止本周,我所担心的小概率问题悉数发生:慢查撑爆空间,双Master主键冲突,迁移过程VIP漂移。做技术的一定不能有侥幸心理,可能会发生的一定会发生……不要纠结于要不要考虑某些小概率风险,而是设计如何规避小概率风险,除非故障的后果真的不重要。 #
  • 背上算法导论,在公司写CodePK。 #
  • 模拟比了一下,感觉有信心了 #
  • 搞出了一次最好成绩,530,哈哈 #
  • 观望今晚的评分,分布式程序没写过,还是串行的,很吃亏。 #
  • code了两千多行才做完地图转换和最短路径的分布算法,分布式程序好难写啊…… #
  • 分组太点背,其他组前2名基本都是百分级的,我这组两个高手,都是千分级的,我Kao,逼我改程序了 #
  • 今天的时间完全花在调分布式接口了,目前依然跟接口对不上,总给我报Crash,一点点的注释程序,就剩个架子了,完全没有指针操作的存在,依然Crash,我已经无语了,这接口估计只有开发的人自己搞的清楚怎么调了。 #
  • 终于找到问题了,不支持memcpy #
  • 把程序串行化交了,看RP吧,至少一件T-shirt是有的 #
  • 真觉得分布式程序调试是真困难……提交上去才知道结果,每次都要等一阵 #
  • 比赛结束,最终搞了个搜索树,用A*启发搜索去搞了。如果平台继续开放的话,周末玩玩还是蛮好的,很多好策略来不及写进去,还有那调用Woker的接口,能不能多个点例子怎么调用,数据序列化各种问题。 #

Powered by Twitter Tools

标签:

项目管理的可控性讨论

3月 29th, 2010 | Posted by | Filed under 项目管理

上学期一篇很扯淡的软件工程报告,仅作存档。

项目管理的可控性讨论

040630520 彭立勋

项目管理中两个重要的内容是进度可控和质量可控。项目进度可控,可以依靠项目生命周期中有三个与时间相关的重要概念,这三个概念分别是: 检查点(Checkpoint)、里程碑(Mile Stone)和基线(Base Line),它们一起描述了在什么时候(When)对项目进行什么样控制。项目质量可控,则是靠建立完善的流程规范,从分析到建模,从编码到测试,再到最后的交付,都要有一套质量可控的规范在运作,它们描述什么人(Who)需要再项目的每个部分做什么(What)。
有了3个W(When/Who/What),就明确了什么人在什么时间做什么事,就能够保证项目的可控。虽然项目的成功依赖的因素远比这些多,但有了可控,至少能保证在规定的时间内现有技术可以解决的问题都可以被实现。

进度可控
项目进度可控,可以依靠项目生命周期中有三个与时间相关的重要概念,这三个概念分别是: 检查点(Checkpoint)、里程碑(Mile Stone)和基线(Base Line),它们一起描述了在什么时候(When)对项目进行什么样控制。

检查点

检查点指在规定的时间间隔内对项目进行检查,比较实际与计划之间的差异,并根据差异进行调整。可将检查点看作是一个固定“采样”时间点,而时间间隔根据项目周期长短不同而不同,频度过小会失去意义,频度过大会增加管理成本。常见的间隔是每周一次,项目经理需要召开例会并上交周报。
例如在我实习的公司,每天都是一个检查点,需要上报每天的工作日志,总监可以根据工作日志来判断每个人的工作情况,对工作较慢的成员进行催促,保证整体进度。然后每周提交任务完成情况,总监根据完成情况判定成员是否努力工作了。将大任务分解成小任务,小任务再分解成可查看的小目标,这样一步步控制,在最小的地方及早发现进度问题,及时催促,保证了项目整体进度不拖延。

里程碑

完成阶段性工作的标志,不同类型的项目里程碑不同。里程碑在项目管理中具有重要意义,用一个例子说明:
情况一:让一个程序员一周内编写一个模块,前3天大家可能都挺悠闲,可后2天就得拼命加班编程序了,而到周末时又发现系统有错误和遗漏,必须修改和返工,于是周末又得加班了。
情况二:实际上还有另一种选择,即周一与程序员一起列出所有需求,并请业务人员评审,这时就可能发现遗漏并即时修改;周二要求程序员完成模块设计并由项目经理确认,如果没有大问题,周三、周四就可让程序员编程。同时项目经理准备测试案例,周五完成测试;一般经过需求、设计确认,如果程序员合格则不会有太大问题,周末可以休息了。
第二种方式增加了“需求”和“设计” 两个里程碑,这看似增加了额外工作,但其实有很大意义:首先,对一些复杂的项目,需要逐步逼近目标,里程碑产出的中间“交付物” 是每一步逼近的结果,也是控制的对象。如果没有里程碑,中间想知道“他们做的怎么样了” 是很困难的。其次,可以降低项目风险。通过早期评审可以提前发现需求和设计中的问题,降低后期修改和返工的可能性。另外,还可根据每个阶段产出结果分期确认收入,避免血本无归。第三,一般人在工作时都有“前松后紧”的习惯,而里程碑强制规定在某段时间做什么,从而合理分配工作,细化管理“粒度”。

基线

指一个(或一组)配置项在项目生命周期的不同时间点上通过正式评审而进入正式受控的一种状态。基线其实是一些重要的里程碑,但相关交付物要通过正式评审并作为后续工作的基准和出发点。基线一旦建立后变化需要受控制。
重要的检查点是里程碑,重要的需要客户确认的里程碑,就是基线。
在我们实际的项目中,周例会是检查点的表现形式,高层的阶段汇报会是基线的表现形式。

质量可控
项目质量可控,则是靠建立完善的流程规范,从分析到建模,从编码到测试,再到最后的交付,都要有一套质量可控的规范在运作,它们描述什么人(Who)需要再项目的每个部分做什么(What)。

需求分析

需求分析指的是在建立一个新的或改变一个现存的电脑系统时描写新系统的目的、范围、定义和功能时所要做的所有的工作。需求分析是软件工程中的一个关键过程。在这个过程中,系统分析员和软件工程师确定顾客的需要。只有在确定了这些需要后他们才能够分析和寻求新系统的解决方法。
只有通过正确的需求分析,才能提炼出客户需求中的对象及数据,以及功能,这是进行开发的关键所在,保证需求分析的质量是保证整个软件工程质量的基础保证。

系统建模

软件工程中的系统建模是指,将需求分析所得到的系统中的对象、数据、功能进行合理的设计、整合,得出满足客户需求的以用代码实现的系统模型。
系统建模的质量决定了系统实现出来的质量,可扩展性、高可用性、系统整体效率都是在系统建模这一层就已经固化,因而系统建模是保证软件质量的最核心部分!

程序编码

无论再好的设计,都是需要靠最终的代码来实现,编码的质量和规范,决定了代码的可读性和可修改性已经程序的效率。
编码中需要有注释规范、排版规范、命名规范、优化规范等等组成,有了这些规范,才能保证每个参与系统开发的人之间代码可以交流,有良好的可维护性。
例如在我实习公司的开发中,我们指定了通用于HTML、JavaScript、Java、PHPSQL等语言的标准命名规范和标准注释规范,这样即使跨不同的语言可以读懂变量及函数的含义,具有两好的可读性,保证代码可维护。另外我们还制定了适用于各种不同语言的排版规范,通过良好的排版,代码的可读性会大大增加,后来的维护人员更容易看懂代码。

系统测试

系统测试是项目进程中的重要部分,测试是保证代码质量的最后一关,编码过程中出现的问题都靠测试环节进行检查。
系统测试分为:单元测试、功能测试、系统集成测试。
单元测试是在软件开发过程中要进行的最低级别的测试活动,在单元测试活动中,软件的独立单元将在与程序的其他部分相隔离的情况下进行测试。
功能测试是根据产品特征、操作描述和用户方案,测试一个产品的特性和可操作行为以确定它们满足设计需求。本地化软件的功能测试,用于验证应用程序或网站对目标用户能正确工作。使用适当的平台、浏览器和测试脚本,以保证目标用户的体验将足够好,就像应用程序是专门为该市场开发的一样。 功能测试也叫黑盒子测试或数据驱动测试,只需考虑各个功能,不需要考虑整个软件的内部结构及代码。一般从软件产品的界面、架构出发,按照需求编写出来的测试用例,输入数据在预期结果和实际结果之间进行评测,进而提出更加使产品达到用户使用的要求。
集成测试是在单元测试的基础上,将所有模块按照设计要求,如根据结构图,组装成为子系统或系统,进行集成测试。实践表明,一些模块虽然能够单独地工作,但并不能保证连接起来也能正常的工作。程序在某些局部反映不出来的问题,在全局上很可能暴露出来,影响功能的实现。
在我实习公司的开发中,主要进行单元测试来保证代码质量,功能测试由业务人员参与,集成测试难度太大,没有进行。

系统交付

在所有的测试完成之后,就是最终的交付了。系统的交付也是需要规范的流程,打包的方式,部署的形式,版本控制,后期维护等等都需要全面的考虑,才能保证客户获得的是高质量的软件。

  项目管理的可控性讨论.pdf (389.7 KiB, 1,287 hits)

标签:

每周推特 2010-03-28

3月 28th, 2010 | Posted by | Filed under 生活轨迹
  • Code Bubbles,为什么没有下载的地址 #
  • 我的博客PR是0,内容有这么差么……飙泪…… #
  • 要在笔记本上装MacOS,不在虚拟机里玩了 #
  • 我的X200啥时候能到我手上哇…… #
  • 我的X200到了,试了下Ubuntu 10.04 beta,体验非常好,觉得就用Ubuntu也行,在我的神舟破本上装个Mac装B好了 #
  • @newcomer2009 公司配的 in reply to newcomer2009 #
  • RT @Fenng:Digg 用客户端排序,而非服务器端排序,据说性能提升了 40 倍 #
  • 折腾Gentoo…… #
  • Linux内核编译ing…… #
  • 经过不断地尝试,终于编译出3M的内核,可以启动我的X200 #
  • 工作也是个调度问题,按优先级排队,分片集中操作,减少任务的切换,可以有效提高工作效率。 #
  • Gentoo真的非常好用,稍微改动一下影响不大的Linux源码,加入个性化定制,编译出的内核只有3M. #
  • 原来xorg -config后黑屏是正常了,难怪我把日志看了一遍都没发现一个error,Xorg能不能设计得像个人类使用的东西,鬼知道黑屏就是正常啊…… #
  • 2005年:人民网发表《云南:遭遇罕见大旱 农民照样增收》。2006年:中新社发表《云南遭遇20年来最严重旱情 被指是山火频袭主因 》。2009年:中国新闻网发表《云南高温大旱 滇池水位急降》。2010年:《云南五十年一遇大旱旱情持续 各界捐款力挺灾区》。 #
  • 2005年:新华网《天降大旱 地质科技引来“保苗水”》。2009年:新华网《云南:灾年粮食获丰收 持续15年增产》。2010年:《西南大旱超五千万人受灾 灾民吃野菜充饥》。这是为什么捏? #
  • 政府撒谎也要查下记录,这忽悠傻子呢…… #
  • 巨多的SQL审核练就了在大脑中生成执行计划的能力…… #
  • RT @newsinchina: RT @love_stef: 本来就是这样啊。我们学校的校园网20元套餐只能访问国内IP和少数国外网站。50的才能有国际网访问权限//如果这是中国大学的普遍现象,那教育部那些叉叉们还梦想着建设世界一流大学//我们也是不一样的价,一流大学做梦去吧 #
  • 用Gentoo唯一的不爽就是无止境的编译,不过对我这种编译控,这是一种乐趣~ #
  • RT @virushuo: 不会这就打起来了吧?这样打下去朝鲜人民比我们先解放啊,太令人不平衡了。 #
  • RT @blogtd: _3月27日的“地球一小时”关灯活动偶们干嘛好呢?_当然是做爱做的事啦!_你坏!那剩下那55分钟呢?_-__-/// #
  • RT @rtmeme: RT @heartboy3 RT @kalhaslichking: 大新闻!我刚刚看的韩国电视SBS台,下面有个字幕!是紧急新闻!刚才朝鲜发动偷袭,击沉韩国军舰,韩国死亡45人,59人幸存,青瓦台召开紧急安全会议!via baidu //国军也得学学 #
  • RT @digitalboy: #20156
    标签:

计数表的技巧

3月 21st, 2010 | Posted by | Filed under 数据库

对于InnoDB及其他一些不能很快统计行数的存储引擎,对于频繁的count(*)操作,就是一种噩梦了,它可能要遍历一遍索引或者数据行才能知道有多少行。

这种时候我们比较容易想到的方法就是设计一个计数表,每次增删记录,就更新这个表:

CREATE TABLE cnt_tbl (
    tbl VARCHAR(20) NOT NULL PRIMARY KEY COMMENT '表名',
    cnt INT UNSIGNED NOT NULL DEFAULT 0 COMMENT '计数'
);

先为要计数的表初始化

INSERT INTO cnt_tbl(tbl, cnt) VALUES('A', 0);

每当A表做一次INSERT,就更新一次计数表

UPDATE cnt_tbl SET cnt = cnt+1 WHERE tbl = 'A';

每当A表做一次DELETE,也更新一次计数表

UPDATE cnt_tbl SET cnt = cnt-1 WHERE tbl = 'A';

需要查询计数时只要做一次查表:

SELECT cnt FROM cnt_tbl WHERE tbl = 'A';

这种方法看似很好,但是如果A表更新频繁,计数表本身会成为一个悲剧。

于是我们做一个小改进,把更新的压力分散到多行,计数的时候做个SUM(需要支持行锁的数据库或存储引擎):

CREATE TABLE cnt_tbl (
    tbl VARCHAR(20) NOT NULL COMMENT '表名',
    slt TINYINT UNSIGNED NOT NULL DEFAULT 0 COMMENT '多个计数槽',
    cnt INT NOT NULL DEFAULT 0 COMMENT '计数',
    PRIMARY KEY (tbl, slt)
);

这里我去掉了cnt列的UNSIGNED属性,为什么呢?因为这里会随机选一个计数槽更新,可能这个槽还没有被+1,但是已经被-1了,于是就有了负数。
可以先初始化256个计数槽

从INSERT INTO cnt_tbl(tbl, slt, cnt) VALUES('A',0,0)
到INSERT INTO cnt_tbl(tbl, slt, cnt) VALUES('A',255,0)

也可以写存储过程一次性搞定。
每当A表做一次INSERT,选择一个槽更新一次计数表

UPDATE cnt_tbl SET cnt = cnt+1 WHERE tbl = 'A' AND slt = RAND()*255;

每当A表做一次DELETE,选择一个槽更新一次计数表

UPDATE cnt_tbl SET cnt = cnt-1 WHERE tbl = 'A' AND slt = RAND()*255;

需要查询计数时需要做一次和:

SELECT SUM(cnt) FROM cnt_tbl WHERE tbl = 'A';

这样已经可以比较分散压力了,但是经常我们count(*)的时候是带有条件的,这又怎么处理呢?

对于带有条件的count(*),假设我们需要按天计数,例如:

SELECT count(*) FROM A WHERE time BETWEEN '2010-03-21' AND '2010-03-22';

我们可以对计数表再做个改进,以达到这个目的:

CREATE TABLE cnt_tbl (
    tbl VARCHAR(20) NOT NULL COMMENT '表名',
    time DATE NOT NULL DEFAULT '0000-00-00' COMMENT 'WHERE条件',
    slt TINYINT UNSIGNED NOT NULL DEFAULT 0 COMMENT '多个计数槽',
    cnt INT NOT NULL DEFAULT 0 COMMENT '计数',
    PRIMARY KEY (tbl, time, slt),
    KEY (time)
);

这种情况下不可能预先插入行的,所以采用ON DUPLICATE KEY UPDATE
每当A表做一次INSERT,选择一个槽更新一次计数表

INSERT INTO cnt_tbl(tbl, time, slt, cnt) 
VALUES('A', CURRENT_DATE(), RAND()*255, 1)
ON DUPLICATE KEY UPDATE cnt = cnt+1;

每当A表做一次DELETE,选择一个槽更新一次计数表

INSERT INTO cnt_tbl(tbl, time, slt, cnt) 
VALUES('A', CURRENT_DATE(), RAND()*255, 1)
ON DUPLICATE KEY UPDATE cnt = cnt-1;

查询某个时间段的计数就可以这么做

SELECT SUM(cnt) FROM cnt_tbl WHERE time BETWEEN '2010-03-21' AND '2010-03-22';

如果需要其他WHERE条件,也可以利用这个思路相应的修改字段。
如果数据已经过期,不再被UPDATE,也可以考虑把它所有的计数槽合并到一个计数槽中,例如slt=0的槽,这样可以减少表的行数。