相關(guān)關(guān)鍵詞
關(guān)于我們
最新文章
- PHP中opcode緩存簡(jiǎn)單用法分析
- thinkPHP控制器變量在模板中的顯示方法示例
- PHP move_uploaded_file() 函數(shù)(將上傳的文件移動(dòng)到新位置)
- dirname(__FILE__)的含義和應(yīng)用說(shuō)明
- thinkPHP5框架實(shí)現(xiàn)分頁(yè)查詢功能的方法示例
- PHP中單雙號(hào)與變量
- PHP獲得當(dāng)日零點(diǎn)時(shí)間戳的方法分析
- Laravel ORM對(duì)Model::find方法進(jìn)行緩存示例詳解
- PHP讀寫(xiě)文件高并發(fā)處理操作實(shí)例詳解
- 【CLI】利用Curl下載文件實(shí)時(shí)進(jìn)度條顯示的實(shí)現(xiàn)
PHP為什么會(huì)被認(rèn)為是草根語(yǔ)言?
PHPer是草根嗎?
從PHP誕生之日起,PHP就開(kāi)始在Web應(yīng)用方面為廣大的程序員服務(wù)。同時(shí),作為針對(duì)Web開(kāi)發(fā)量身定制的腳本語(yǔ)言,PHP一直秉承簡(jiǎn)單、開(kāi)源的思想,這也使得PHP得以快速的發(fā)展,并且大力地推動(dòng)Web2.0的出現(xiàn)與發(fā)展。但是,長(zhǎng)期以來(lái),PHPer(PHP Programmers)被認(rèn)為是處于草根階層的程序員,被認(rèn)為是技術(shù)含量少,層次低的程序員。這點(diǎn)在國(guó)內(nèi)尤其突出。
記得一個(gè)技術(shù)主管說(shuō)過(guò)這樣一個(gè)事情。他給一個(gè)程序員分配了PHP的開(kāi)發(fā)任務(wù),沒(méi)想到那個(gè)程序員居然說(shuō):“我是學(xué)Java出身的,你讓我去寫(xiě) PHP,你這不是在貶低我嗎?”。這件事情給我印象很深、觸動(dòng)也很大。雖然這不能代表大部分程序員的看法,但是這么認(rèn)為的人應(yīng)該不少。還有人說(shuō),現(xiàn)在如果是大型的政府項(xiàng)目,PHP是肯定不會(huì)被列入考慮的范圍之內(nèi)的。
那么為什么PHPer會(huì)被認(rèn)為是草根階層,是因?yàn)樗芎?jiǎn)單,人人都可以學(xué)會(huì),所以沒(méi)什么難度嗎?我以前也是這么認(rèn)為。PHP入門(mén)很快,處理文件,數(shù)據(jù),遠(yuǎn)程連接,網(wǎng)絡(luò)編程都非常方便,官方也有這樣的說(shuō)法:PHP學(xué)習(xí)的成本很低,所以你容易去使用它。這個(gè)想法也是普遍的,甚至大部分的PHPer 自己都這樣認(rèn)為。
說(shuō)到這里,我想大家就會(huì)想到我為什么要寫(xiě)這些文字。因?yàn)橐荒甓嗟腜HP推廣工作讓我了解到許許多多的使用PHP的公司的大概情況。在這些過(guò)程中我慢慢體會(huì)到其中的根本原因。這里我說(shuō)是根本原因雖然是個(gè)人的看法,但是我覺(jué)得事實(shí)就是如此。
那么為什么PHPer會(huì)被看成草根階層,根本原因是PHPer所作的事情(通過(guò)代碼實(shí)現(xiàn))的絕大部分都是表現(xiàn)層的東西,這個(gè)熟悉PHP的人都知道。當(dāng)然也會(huì)有PHP會(huì)說(shuō)他用MVC結(jié)構(gòu)編寫(xiě)的某某框架具備的如何如何的功能。但是這些還是表現(xiàn)層。所以只會(huì)處理表現(xiàn)層的程序員就被看成草根階層了。事實(shí)上也是如此,因?yàn)檫@種情況下PHP確實(shí)很難構(gòu)造大型的應(yīng)用。
這就找到原因了,不是的。為什么PHPer總是在負(fù)責(zé)表現(xiàn)層的東西呢。答案是底層的數(shù)據(jù)處理(Web應(yīng)用就是數(shù)據(jù)存儲(chǔ)和查找)我們一般不去觸及。好,那么說(shuō)到這里有些人可能已經(jīng)想到了,那不就是數(shù)據(jù)庫(kù)嗎?對(duì),就是數(shù)據(jù)庫(kù)。讓PHPer一直當(dāng)草根的元兇就是數(shù)據(jù)庫(kù)。為什么?
PHPer對(duì)MySQL的依賴過(guò)大
因?yàn)槟壳傲餍械膚eb架構(gòu)中,前端是負(fù)載均衡系統(tǒng),中間是web服務(wù)器,后面是數(shù)據(jù)庫(kù)服務(wù)器。所以,大部分PHPer工作在Web服務(wù)器層面。因?yàn)閿?shù)據(jù)庫(kù)已經(jīng)很好地為我們組織數(shù)據(jù)了。所以PHP中沒(méi)有太多的算法,而且大家潛意識(shí)下也覺(jué)得不需要,更何況會(huì)影響性能。
這種情況下,PHPer就成為了數(shù)據(jù)庫(kù)使用者,他總是在操作數(shù)據(jù)庫(kù)。而不是在做程序。一個(gè)最簡(jiǎn)單的PHP腳本就是,連接數(shù)據(jù)庫(kù),把數(shù)據(jù)取出來(lái),然后用命令輸出到瀏覽器。整個(gè)過(guò)程不超過(guò)10行代碼。給人的感覺(jué)就是太簡(jiǎn)單了。沒(méi)有任何技術(shù)含量。為什么了,因?yàn)閿?shù)據(jù)處理部分都已經(jīng)被數(shù)據(jù)庫(kù)做完了。尤其是MySQL的使用。MySQL是免費(fèi)的,所以大多數(shù)程序員可以自由地使用它,另外MySQL的速度夠快了,所以做個(gè)PHP應(yīng)用程序非常的簡(jiǎn)單。這就相當(dāng)于給你槍以后你覺(jué)得沒(méi)有必要學(xué)習(xí)武功一樣。當(dāng)然,我不是說(shuō)槍沒(méi)有武功好。而是說(shuō),槍的出現(xiàn),小孩都可以輕松便捷地殺人了。
我們?cè)僭敿?xì)說(shuō)說(shuō)為什么是數(shù)據(jù)庫(kù)。這里我說(shuō)一個(gè)例子。我去過(guò)北京一家非常著名的網(wǎng)站,當(dāng)時(shí)我們還有一個(gè)比較資深的PHP程序員在那說(shuō)些系統(tǒng)架構(gòu)的事情。我記得當(dāng)時(shí)那個(gè)程序員問(wèn)大家一個(gè)數(shù)據(jù)結(jié)構(gòu)中的算法問(wèn)題的時(shí)候,全場(chǎng)沒(méi)有一個(gè)人能答得出來(lái)(包括我)。然后那個(gè)程序員就開(kāi)始給大家講些很基礎(chǔ)的數(shù)據(jù)結(jié)構(gòu)的東西了。讓我一下子回想到大學(xué)時(shí)候?qū)W的數(shù)據(jù)結(jié)構(gòu)課。而這些基礎(chǔ)的數(shù)據(jù)排序、查找、傳遞的問(wèn)題在其他高級(jí)語(yǔ)言(比如C)是非常普遍的。但是在PHP沒(méi)有。PHPchina.com的論壇也有個(gè)板塊叫PHP的數(shù)據(jù)結(jié)構(gòu)和算法。這個(gè)板塊的帖子也是寥寥無(wú)幾。
說(shuō)到這里,大家明白了吧?大部分PHPer僅僅處理表現(xiàn)層的東西,而在MySQL的便捷使用下,PHPer幾乎不用觸及任何數(shù)據(jù)結(jié)構(gòu)與算法的情況下完成大部分開(kāi)發(fā)任務(wù),所以一個(gè)才有上面的,沒(méi)有一個(gè)PHP程序員能夠回答出那道數(shù)據(jù)結(jié)構(gòu)的問(wèn)題,換成是C等語(yǔ)言,情況可能就大不相同了。是PHPer草根,才讓PHP顯得草根。
仔細(xì)回想下,目前網(wǎng)絡(luò)上大家討論的最多的是兩個(gè)方面的問(wèn)題。一個(gè)是PHP的類的使用(處理過(guò)程的封裝),還有一個(gè)是開(kāi)發(fā)框架問(wèn)題。但是我們仔細(xì)分析的話,發(fā)現(xiàn)這些所謂的PHP中比較復(fù)雜的概念里面沒(méi)有數(shù)據(jù)處理。為什么,有數(shù)據(jù)庫(kù)。用一個(gè)Adodb或者PHP5的PDO就可以搞定了。真的搞定了嗎?不是,這些無(wú)非是在連接數(shù)據(jù)庫(kù),沒(méi)有數(shù)據(jù)處理。所以PHPer似乎就沒(méi)有什么可以拿出臺(tái)面上的東西。
再說(shuō)一個(gè)具體的代碼問(wèn)題,無(wú)級(jí)分類。這個(gè)概念我想大家都不會(huì)陌生了吧。我見(jiàn)過(guò)兩種處理方式。第一個(gè)是地道的PHPer的處理方式,也是目前比較流行的。就是用數(shù)據(jù)庫(kù)來(lái)處理。而且字段很少,只需要加個(gè)父類的字段并加以判斷就行了。而且這個(gè)方法很實(shí)用。效率也高。但是這個(gè)不是數(shù)據(jù)處理的范疇了,而是數(shù)據(jù)庫(kù)的查找。
第二個(gè)是C程序員用PHP寫(xiě)出來(lái)的,他把所有的分類信息都從數(shù)據(jù)庫(kù)取出來(lái),然后用數(shù)據(jù)結(jié)構(gòu)算法進(jìn)行排列分布,然后輸出。
這里我們不對(duì)這兩種方式的效率進(jìn)行對(duì)比,我想大家都有各自的想法。但是我想說(shuō)明一個(gè)問(wèn)題,就是這兩種做法的本質(zhì)的區(qū)別。PHPer習(xí)慣性地用數(shù)據(jù)庫(kù)來(lái)處理,而且有很巧的處理方式,效率也很高。這種方式就是數(shù)據(jù)庫(kù)查詢。而第二種方法是比較有特點(diǎn)的。他認(rèn)為數(shù)據(jù)庫(kù)就是存放數(shù)據(jù)的地方,具體的邏輯處理還要靠自己的邏輯。
因此,結(jié)論是第二種方法的使用者覺(jué)得自己強(qiáng)些,因?yàn)閿?shù)據(jù)的邏輯是他組織的。并且覺(jué)得PHPer的那種做法無(wú)非就是會(huì)查詢數(shù)據(jù)庫(kù)罷了。所以他認(rèn)為PHPer是草根級(jí)的,只懂得操作數(shù)據(jù)庫(kù)和排列頁(yè)面(smarty搞搞那種)。
讓數(shù)據(jù)庫(kù)回歸本職工作
說(shuō)到這里,我想大家都已經(jīng)回憶了不少自己平時(shí)用PHP做開(kāi)發(fā)的經(jīng)歷了吧,是否發(fā)現(xiàn)大家確實(shí)都在操作數(shù)據(jù)庫(kù)呢。
那么我們來(lái)討論下這個(gè)問(wèn)題。數(shù)據(jù)庫(kù)不好嗎?為什么我一直用數(shù)據(jù)庫(kù)處理數(shù)據(jù)都沒(méi)有問(wèn)題。我要說(shuō)的是數(shù)據(jù)庫(kù)是有問(wèn)題的,而且有很大的問(wèn)題。當(dāng)然這里我并不是說(shuō)不能用數(shù)據(jù)庫(kù),也不是在貶低數(shù)據(jù)庫(kù)的性能。而是,我們沒(méi)有充分認(rèn)識(shí)到數(shù)據(jù)庫(kù)所起到的作用。
我的想法源起于這樣一個(gè)事情,有一次一個(gè)網(wǎng)站的技術(shù)總監(jiān)問(wèn)我,為什么他們的網(wǎng)站那么慢,要怎么辦。當(dāng)時(shí),我的MSN里Zend總部的工程師正好在線,我就問(wèn)他PHP響應(yīng)比較慢了,怎么辦?他當(dāng)時(shí)直接告訴我,是數(shù)據(jù)庫(kù)問(wèn)題??隙ㄊ菙?shù)據(jù)庫(kù)沒(méi)有優(yōu)化設(shè)計(jì)好。所以,我沒(méi)有給那個(gè)技術(shù)總監(jiān)確切的答案了,因?yàn)樗麄兊臄?shù)據(jù)庫(kù)設(shè)計(jì)我們是不能涉及的。所以就給了大概的數(shù)據(jù)庫(kù)優(yōu)化的建議。這樣的事情屢次發(fā)生,我就開(kāi)始懷疑,為什么Zend總部的工程師每次都跟我說(shuō)是數(shù)據(jù)庫(kù)的問(wèn)題呢,難道我們不能從PHP層面來(lái)解決這個(gè)問(wèn)題嗎?答案是不能。因?yàn)镻HP目前的運(yùn)行速度已經(jīng)是很快了,通過(guò)Zend的性能分析也能看到一個(gè)用戶的點(diǎn)擊,PHP的運(yùn)行時(shí)間只有10%不到,那PHP在干嗎?它在等。等數(shù)據(jù)庫(kù)的查詢結(jié)果。這個(gè)方面在目前的PHP產(chǎn)品中有了很大的提高,那就是 Caching和網(wǎng)頁(yè)靜態(tài)化兩個(gè)方案。
Caching可能大家會(huì)比較陌生,但是網(wǎng)頁(yè)靜態(tài)化現(xiàn)在連PHP產(chǎn)品的用戶都非常清楚了。速度快、容易被搜索到等等,好處不言而喻。開(kāi)玩笑地說(shuō),現(xiàn)在網(wǎng)站的主頁(yè)實(shí)現(xiàn)網(wǎng)頁(yè)靜態(tài)化只需要硬盤(pán)足夠大。J至于Caching就比較復(fù)雜些,也是大多數(shù)PHPer感到頭疼的地方。甚至于有些人會(huì)用C來(lái)實(shí)現(xiàn)。因?yàn)镃aching中的數(shù)據(jù)有效期驗(yàn)證、查找、提取、更新等等都是比較難處理。當(dāng)然,也有人會(huì)用數(shù)據(jù)庫(kù)來(lái)處理 Caching問(wèn)題。
所以,當(dāng)訪問(wèn)量激增的時(shí)候,PHP架構(gòu)的網(wǎng)站會(huì)出現(xiàn)的很多問(wèn)題都因數(shù)據(jù)庫(kù)而起。數(shù)據(jù)庫(kù)的同步問(wèn)題還不算什么。關(guān)鍵是數(shù)據(jù)庫(kù)的響應(yīng)速度會(huì)有指數(shù)級(jí)的降低。這個(gè)問(wèn)題我在10月23號(hào)LAMP發(fā)布會(huì)的時(shí)候問(wèn)過(guò)MySQL的副總裁。他當(dāng)時(shí)也沒(méi)有給我比較完美的答案(這也我的意料之中),因?yàn)閿?shù)據(jù)庫(kù)總會(huì)有瓶頸的,除非是神仙數(shù)據(jù)庫(kù),哈哈!
這里有個(gè)題外話,LAMP大會(huì)的時(shí)候我跟Yahoo的一個(gè)技術(shù)高管聊的時(shí)候,我問(wèn)他Yahoo在選擇MySQL還是Oracle的時(shí)候是怎么考慮,他的答案令我非常驚訝。他說(shuō)大部分的時(shí)候我們是會(huì)用MySQL的,因?yàn)樗男阅芤呀?jīng)達(dá)到我們的要求。但是什么時(shí)候我們會(huì)選用Oracle呢,就是當(dāng)我們需要存儲(chǔ)收費(fèi)用戶的數(shù)據(jù)的時(shí)候。我就問(wèn)為什么,難道Oracle比MySQL穩(wěn)定嗎?他說(shuō),這個(gè)倒沒(méi)有特別考慮。關(guān)鍵是如果使用Oracle的話,當(dāng)出現(xiàn)問(wèn)題的時(shí)候我們可以找到負(fù)責(zé)人,Oracle會(huì)負(fù)責(zé)事故的處理,但是如果用MySQL的話,我們找誰(shuí)去?
所以,我們對(duì)數(shù)據(jù)庫(kù)的看法應(yīng)該糾正過(guò)來(lái),就是說(shuō)數(shù)據(jù)庫(kù)不是萬(wàn)能的。如果有實(shí)力的話自己開(kāi)發(fā)數(shù)據(jù)庫(kù)。聽(tīng)說(shuō)Google就是那樣的。
那么我們?cè)趺纯创龜?shù)據(jù)庫(kù)呢?我個(gè)人的理解是數(shù)據(jù)庫(kù)只是用來(lái)降低開(kāi)發(fā)成本的手段。因?yàn)椴捎脭?shù)據(jù)庫(kù)以后我們不需要考慮數(shù)據(jù)的存儲(chǔ),尤其是排序和查找。但是這會(huì)帶來(lái)什么問(wèn)題呢?就是當(dāng)業(yè)務(wù)膨脹的時(shí)候,數(shù)據(jù)庫(kù)就成為瓶頸了。這個(gè)時(shí)候問(wèn)題就會(huì)非常棘手。因?yàn)檫@個(gè)是底層的數(shù)據(jù)處理。牽一發(fā)而動(dòng)全身。
所以我認(rèn)為正確的觀點(diǎn)是,數(shù)據(jù)庫(kù)是一個(gè)數(shù)據(jù)備份機(jī)。怎么理解,我們只需要保證數(shù)據(jù)的存儲(chǔ)有效性就行了。而這本來(lái)就是數(shù)據(jù)庫(kù)的核心功能,只不過(guò)因?yàn)閿?shù)據(jù)庫(kù)的方便的排序等功能讓大家把過(guò)多的處理都交給數(shù)據(jù)庫(kù)來(lái)操作了。一個(gè)用戶的點(diǎn)擊PHP就把一大堆的任務(wù)交給數(shù)據(jù)庫(kù),然后把結(jié)果排列下給用戶就完事了。這對(duì)數(shù)據(jù)庫(kù)是不公平的。也是因此大家開(kāi)始抱怨數(shù)據(jù)庫(kù)的性能了。
針對(duì)這個(gè)觀點(diǎn),我們?cè)倥e個(gè)例子,有一次我去拜訪一個(gè)大型的網(wǎng)絡(luò)公司(基本上國(guó)內(nèi)只要上過(guò)互聯(lián)網(wǎng)的都知道),他們使用PHP很少,但是我了解到他們其它業(yè)務(wù)是怎么使用數(shù)據(jù)庫(kù)。他們自豪地跟我介紹說(shuō)他們?cè)跀?shù)據(jù)庫(kù)的外圍有個(gè)第二數(shù)據(jù)庫(kù)(我這里起名叫第二數(shù)據(jù)庫(kù))。為什么叫第二數(shù)據(jù)庫(kù)呢,原來(lái)它是一個(gè)緩存系統(tǒng)。那么開(kāi)發(fā)工程師怎么去這個(gè)緩存系統(tǒng)獲取數(shù)據(jù)呢?那個(gè)技術(shù)總監(jiān)自豪地說(shuō),他們這個(gè)緩存系統(tǒng)有SQL查詢語(yǔ)句。我當(dāng)時(shí)很驚訝,但是后來(lái)想想確實(shí)需要這個(gè)。因?yàn)楫?dāng)你的緩存系統(tǒng)達(dá)到一定量級(jí)的時(shí)候從緩存獲取數(shù)據(jù)都非常復(fù)雜,干脆寫(xiě)個(gè)SQL查詢語(yǔ)句讓緩存系統(tǒng)分析、處理并返回?cái)?shù)據(jù)。而且他們告訴我,在他們那里,就算是用PHP的話也是讓PHP去那個(gè)緩存系統(tǒng)讀取數(shù)據(jù)。
所以說(shuō),如果你能處理好這樣的問(wèn)題的話,把數(shù)據(jù)存放在數(shù)據(jù)庫(kù),然后數(shù)據(jù)庫(kù)只起到備份的作用。然后你用自己的中間層來(lái)處理分析數(shù)據(jù),效果是90% 以上的用戶不訪問(wèn)數(shù)據(jù)庫(kù)。有人就會(huì)說(shuō)了,這不就類似連接池的東西嗎?是的,因?yàn)閿?shù)據(jù)庫(kù)的瓶頸是無(wú)法解決的,我們只能在Web服務(wù)器和數(shù)據(jù)庫(kù)中間加個(gè)中間層來(lái)做緩沖。
可能大家會(huì)說(shuō)了,切,這個(gè)我們?cè)缇椭懒?。那好,這里我要說(shuō)的是它引發(fā)的兩點(diǎn)思考:
第一,有些語(yǔ)言已經(jīng)有連接池技術(shù)的基礎(chǔ)上,那些程序員可以方便地使用連接池而構(gòu)建大型應(yīng)用。那么如果他們認(rèn)為 PHPer只會(huì)是用數(shù)據(jù)庫(kù),那么我們是不是可以說(shuō)他們只會(huì)是用連接池呢?連接池和數(shù)據(jù)庫(kù)在這個(gè)概念上有何區(qū)別?
第二,當(dāng)PHPer開(kāi)始構(gòu)建自己的緩存系統(tǒng)的時(shí)候,他是不是突破了PHPer只會(huì)是用數(shù)據(jù)庫(kù)的層次?因?yàn)樗麉⑴c了數(shù)據(jù)邏輯的處理工作。那么他還是草根嗎?
最后,懂得獨(dú)立思考的PHPer不是草根,什么事情都丟給數(shù)據(jù)庫(kù)去做的才是。