数据库

对《Smarty的分页实现》一文的最后回复

[引子] 前两天在网上看到一篇谈(针对小项目的)web分页实现的文字(见此),其做法是丛数据库中取出所有记录集(而不管实际需要哪页的记录集),然后用空循环的方式定位到指定的记录集所在位置并提取。由此引发一通讨论。本文是deminy对该文的最后回复。

本文涉及到的关键字: PHP Smarty ADOdb 数据库分页


1. 你在评论中说,你“不是经不起批评”,而是我的口气让人不爽。抱歉,实在是因为你的设计中的缺陷太明显、太典型了,是一种设计思想上的严重缺陷,而这种思想是每个技术人员都应该避免和制止的,让人不得不说。难道你的作品就批评不得?难不成我批评的时候还要刻意的先恭维恭维你?被人批评后感觉爽不爽要看对方的言辞,但也要看自己对批评的理解和觉悟。我顺手指出你的问题所在,你就从点到面地开始反驳起来。既然彼此都不易不饶,那我也只好奉陪了。 :D

2. 我相信你曾花了(点)时间研究过别人的(数据库)分页技术,但是如果你细看一下的话,你会发现,别人的分页技术都没有采用你的思路,为什么?很简单,因为你的思路是(完全)不可取的。不要以为那些分页技术的设计者们比你差,恰恰相反,他们对具体技术的应用往往比你久,他们的实战经验往往比你丰富得多(得多),而且,他们的智商往往也不低于你。

3. 你文中说“不过分页类库不一定适合Smarty,特别是当记录集数据是二维数组时”。希望你再去好好研究一下Smarty的文档、然后再写点程序测试一下再这么说吧。事实上,Smarty支持多维数组都是没有问题的。其实,Smarty比别的绝大多数模板厉害的其中一点就在于别的模板引擎绝大多数无法支持多维数组变量(甚至连一维数组都不支持),而Smarty可以。对于基于PHP+DB的项目来讲,在模板引擎中对多维数组变量的支持是非常重要的,因为数据库的结果集是以数组的形式返回的。4

4. 你在评论中说,“但是希望有深入的讨论,而不是这样的泛泛而谈。 ”。在我前面的几篇讨论中,我已经清晰、具体地告诉你,你的设计的“致命伤在于浪费资源,而且是没有意义地在浪费资源。”;我还提到,单就MySQL而言,它的分页类也是比较难设计的,并指出主要的原因;后来,我还告诉你,我具体地查了一下ADOdb的分页技术(实际上我是翻阅了其中几处关键代码),认为ADOdb的分页技术可以直接应用,因此可以不必要自己再费劲去设计分页;最后,我还清晰、具体地告诉你,几种数据库(例如MySQL/Oracle/MS SQL)的分页技术是不一样的,因此好的(通用的)分页类是很难写的;在本文的讨论中,你还会看到我对Smarty和ADOdb的一些具体技术方面的讨论。我想,你不会再以为我还是在和你“泛泛而谈”了吧?

5. 你在评论中说,“分页类要是还依赖于数据库,那都耦合成什么样了,怎么扩展。”。很抱歉,这点我懒得评论,浪费口舌。我只能认为你的数据库开发经验还是肤浅的。分页这项需求是紧密地和数据库相关的,如果没有数据库,那么也就不需要这么费劲地讨论分页问题了;分页类的设计是一项非常具体的web技术应用,而不是一种泛泛的理论、一种泛泛的思路,可以被随便挂在嘴上当做谈资。如果你对一项技术的具体应用不是很熟悉,就不要试图发表一些不够成熟的、却又貌似权威的看法。(顺便问一句,如你所说若分页类需要扩展的话,分页类的扩展方向是什么?)

6. 你在评论中说,你的设计思路是“数据库->分页类。分页类是完全独立的,类中不包括其它任何对象。”。的确,你说“分页类是完全独立的”是正确的,但那是因为你的分页类根本就没做记录集分页的核心部分。基本上来讲你的分页类主要是实现了输出不同页码(坦率的说,这属于分页技术里面的边角料的活,初级程序员都可以用几个循环来实现)和显示结果记录集,但是最关键的记录集查询时候的分页你却没做,而却把它交给了Smarty,而且让Smarty去用一种低级的手法去实现。

7. 至于你文中所说的“看到一个号称分页类终结者的,哈哈,有点好笑。分页类中把SQL都包含进去了,这个是绝对不能容忍的,可以说作者对OO的认识还比较浅。”,显然也是荒谬的,该被好笑的是你。分页(原则上)是用SQL实现的,当然要用到SQL,而且这跟OO(面向对象)没什么关系。如果你只会这么生搬硬套OO的概念,建议你还是再实战两年后再讨论吧。

8. 你在评论中说,“而deminy(的思路)是 分页类(包含数据库连接)。 ”。这点你倒说对了,没有数据库连接,是没法(有效)分页的。注意,我说的是有效(率)的分页。这点是一目了然的。如果这点你都不能理解,你最好先好好地开发几个基于数据库的产品/项目后再来讨论吧(不要把业余的留言本等也当成项目)。

9. 你在评论中说,如果用ADOdb的话,万一“换了个数据库系统,你又要重写分页部分的代码。 ”,“但是ADODB并不是大家开发的标准,不是所有人都用数据库抽象层。很多项目就是针对某种数据库的,如果需要作数据库移植,你就连分页类都要修改”,这两句话毫无正确性可言,而且我已经明确告诉你了,“ADOdb对于分页的处理机制比较好”。如果把你的这两句话贴给那些用过ADOdb的技术人员去看看的话,他们会笑话你一知半解的。我想你对ADOdb没有深入了解过,对ADOdb的数据集处理机制你更没有研究过。

10. 你在评论中说,“分页就是两个思路:一种整个结果集读入内存,只需要一次查询,占用内存多,但效率高;另一种读取部分记录,多次对数据库查询,占用内存少,效率视情况而定,如果用户多,数据库并发查询数目过多也可能导致一些问题。 ”。我建议你讨论的时候不要一时冲动而说一些很不严谨的话。单就我们当前讨论的简单话题(从数据库查询记录后分页输出)而言,把你这段话随便拿给绝大多数的数据库相关开发人员(不管是用VB/C++/Delphi/Java的,还是DBA)看,都会告诉你不妥的。前一种思路在web上一无可取之处,连Java web server这种使用了服务器端cache技术的服务器都不会这样做。

11. 你在评论中说,你认为“面对不同规模的项目就是要采用不同的方法。”。是地,这句话没错,但是一些基本原则还是要遵循的。退一步而言,你用这样的垃圾思路在小项目中也的确无妨的,但如果把它当成一个经验贴出来,那可是贻笑大方的。

12. 别的方面(例如软件架构、软件设计模式)等话题就太广了,争议更多,说出来都是扯皮了。

13. 再退一步来讲的话,你可以说你的讨论仅限于Smarty,而不涉及数据库问题。即使这样的话,你也可以检查检查你的那段循环取值程序(这是你的设计中的两个主要部分之一),看看是不是很垃圾:

{section name="list" loop=$productID start=0 max=$pager_Total step=1}
{if ($smarty.section.list.index >= $pager_StartNum )&& ($smarty.section.list.index <= $pager_EndNum )}
......


简洁来写就是:

for (i = 0; i < size_of_array; i++)
if ((i >= a) && (i <= b))
// do sth here.这段是伪代码,不是PHP代码


看出来你的程序的问题了没有?你试图从数组中取一个区间(例如区间(a,b)),于是你用了一个空循环从数组开始的地方一直空循环到a,然后取出a到b的元素,然后继续空循环到数组末尾!3不要跟我说while/for/section这类的循环结构是应该这样用来对数组操作的。(如果你还不懂在Smarty中如何更有效率地写这段代码的话,那就去好好读读Smarty中相关文档吧)

大体上来讲,从你文中使用的技术(Smarty)来看是你是个中级程序员的水平,但从你文中对数据库知识的理解、从你的程序设计能力以及由此反映出来的程序设计思想水平来看,是个初级程序员的水准。

14. 另外,从头到尾你都在偏执地、教条地理解我的意思,教条地套用软件开发中的“教科书”言论来解释事理,却缺乏具体的、有说服力的实战例子(例如具体的有价值的项目应用)。在这篇讨论中,你也许知道某些技术名词,但不知道些技术名词的具体含义,但你却试图在你不熟悉、不大了解的技术方面充当行家和权威。在这篇讨论中,你对概念僵硬地套用的能力超越了你对概念具体应用的能力。也许在网上,对概念的夸夸其谈更能够吸引眼球,但更能推动技术进步的做法是对概念的实际应用。(顺便说一句,我也很看不起拉大旗做虎皮的人。)

15. 看看吧,你的一篇原创文字(包括回复),在技术上有如此众多可以被他人指正的地方,并且连入门级的(技术方案设计)思路都没有端正,然后你还好意思说你是在义务地给我“普及知识”?你以为你有这个资格?太可笑兼无知了。

16. 不要认为你能够翻译、转载一些有价值的技术文字就代表你的水平好,就代表你就是权威。翻译技术文字不代表你理解了其中的意思,就像很多翻译计算机书籍的人,自己都不大懂书里面说的是什么。顺便说一句,我还是很赞赏你翻译文章的行为的(因为的确很有必要),但是要记得尊重版权、尊重原作者,而且,也要尊重原文的原始意思。

完。

[注1] 原讨论见此本地镜像 (取自2005-11-14 16:42:39左右)。

[注2] 居然为讨论这么低级、浅显的技术问题而花了这么多篇幅,惭愧。谢绝在本站继续讨论这个问题。

[注3] 这段代码的问题在于其执行一些不必要的空循环操作,在无意义地浪费资源。这个问题是可以通过简单地改写一下代码就可以解决的,如下所示:

for (i = a; i <= b; i++)
// do sth here.这段是伪代码,不是PHP代码


对小项目来讲,这点资源的浪费的确不是很重要,但是其中反映出来的程序设计思想是欠佳的。另外,关于效率问题,请参阅我的一篇文字《为什么程序效率仍然很重要》。2005-11-14 21:24:51


[注4] 此段讨论误解了原作者(haohappy)意思,删除。2005-11-15 01:03:11

[注5] 对你最新回复的回复

前五点不评价,或者不再讨论。但下面会讨论一下你在第六点后面的一些话题。

你说,“我做过的数据库应用应该不比你少,你叫我去实战?你拿出一个我完全没有做过的数据库应用吧? 或者你自己得意的一套数据库相关代码出来让我分析一下?”Hoho,如果攀比彼此做过的数据库应用多少,我想是没有多大意思的。但是如果你真要比的话,那我告诉你,我在tom.com工作期间(14个月),相当一段时间是带领一个团队负责tom整个网站大部分在线互动程序(PHP为主)的开发的。考虑一下整个门户网站对在线互动程序的需求,你自己算算我可能经手过多少个项目吧(你没有这种经历,是无法想象的)。

你也许会说,“你经手那么多项目,不一定都是你做的呀”。是的,但是每个项目如何实现我都要先大体考虑清楚后才能给其他同事去做(实际上我自己也要自己动手做很多项目);如果我不能在某些方面服众,我就无法领导好一个团队。我觉得,我在tom工作期间的表现是基本称职的。

你也许还会说,“你做过很多项目不一定代表你牛啊、不一定代表你水平高啊”。是的,从编程能力来讲,我从来没有把自己当成一个高级程序员的水平,我对自己现在的编程能力的定位也就是一个很称职的中等偏上的程序员水平。我有时候会对朋友说,我说我不喜欢自己写程序,因为我写出来的程序不属于最漂亮的行列;但是,我的眼光比我的编程能力高,我能够看到好些一般程序员看不到的问题,这就是为什么我大概只有中级程序员的编程水平、但却具备中级偏上的素质。

另外,成为高级程序员不是我的追求。我眼高手低,我更喜欢的是借用别人的代码实现自己的思路,我更欣赏的是别人的代码和思想,例如Smarty的设计,就是我非常推崇的一套设计方案(虽然我没有大规模用过它)。

这种比较是无聊的。自信心不需要靠这样的攀比来建立的。每个人都有优点和缺点的。

最后,过两天我会隐藏(不是删除)这篇文字的,一则我不喜欢自己帖子里面有不妥的过激言论,二则我不喜欢技术争论,三是影响我修行的效果,尤其在我修行尚未到家的时候 :$。2005-11-15 01:09:56

类别: