PHP開發者常犯的(de)10個(gè)MySQL錯誤
數據庫是Web大(dà)多(duō)數應用(yòng)開發的(de)基礎。如果你是用(yòng)PHP,那麽大(dà)多(duō)數據庫用(yòng)的(de)是MYSQL也(yě)是LAMP架構的(de)重要部分(fēn)。
PHP看起來(lái)很簡單,一個(gè)初學者也(yě)可(kě)以幾個(gè)小時(shí)内就能開始寫函數了(le)。但是建立一個(gè)穩定、可(kě)靠的(de)數據庫确需要時(shí)間和(hé)經驗。下(xià)面就是一些這(zhè)樣的(de)經驗,不僅僅是MYSQL,其他(tā)數據庫也(yě)一樣可(kě)以參考。
1.使用(yòng)MyISAM而不是InnoDB
MySQL有很多(duō)的(de)數據庫引擎,單一般也(yě)就用(yòng)MyISAM和(hé)InnoDB。
MyISAM 是默認使用(yòng)的(de)。但是除非你是建立一個(gè)非常簡單的(de)數據庫或者隻是實驗性的(de),那麽到大(dà)多(duō)數時(shí)候這(zhè)個(gè)選擇是錯誤的(de)。MyISAM不支持外鍵的(de)約束,這(zhè)是保證數據完整性的(de)精華所在啊。另外,MyISAM會在添加或者更新數據的(de)時(shí)候将整個(gè)表鎖住,這(zhè)在以後的(de)擴展性能上會有很大(dà)的(de)問題。
解決辦法很簡單:使用(yòng)InnoDB。
2.使用(yòng)PHP的(de)mysql方法
PHP從一開始就提供了(le)MySQL的(de)函數庫。很多(duō)程序都依賴于mysql_connect、mysql_query、mysql_fetch_assoc等等,但是PHP手冊中建議(yì):
如果你使用(yòng)的(de)MySQL版本在4.1.3之後,那麽強烈建議(yì)使用(yòng)mysqli擴展。
mysqli,或者說MySQL的(de)高(gāo)級擴展,有一些優點:
有面向對(duì)象的(de)接口
prepared statements(預處理(lǐ)語句,可(kě)以有效防止SQL-注入攻擊,還(hái)能提高(gāo)性能)
支持多(duō)種語句和(hé)事務
另外,如果你想支持多(duō)數據庫那麽應該考慮一下(xià)PDO。
3.不過濾用(yòng)戶輸入
應該是:永遠(yuǎn)别相信用(yòng)戶的(de)輸入。用(yòng)後端的(de)PHP來(lái)校驗過濾每一條輸入的(de)信息,不要相信Javascript。像下(xià)面這(zhè)樣的(de)SQL語句很容易就會被攻擊:
$username = $_POST["name"]; $password = $_POST["password"]; $sql = "SELECT userid FROM usertable WHERE username='$username'AND password='$password';"; // run query...
這(zhè)樣的(de)代碼,如果用(yòng)戶輸入”admin’;”那麽,就相當于下(xià)面這(zhè)條了(le):
SELECT userid FROM usertable WHERE username='admin';
這(zhè)樣入侵者就能不輸入密碼,就通(tōng)過admin身份登錄了(le)。
4.不使用(yòng)UTF-8
那些英美(měi)國家的(de)用(yòng)戶,很少考慮語言的(de)問題,這(zhè)樣就造成很多(duō)産品就不能在其他(tā)地方通(tōng)用(yòng)。還(hái)有一些GBK編碼的(de),也(yě)會有很多(duō)的(de)麻煩。
UTF-8解決了(le)很多(duō)國際化(huà)的(de)問題。雖然PHP6才能比較完美(měi)的(de)解決這(zhè)個(gè)問題,但是也(yě)不妨礙你将MySQL的(de)字符集設置爲UTF-8。
5.該用(yòng)SQL的(de)地方使用(yòng)PHP
如果你剛接觸MySQL,有時(shí)候解決問題的(de)時(shí)候可(kě)能會先考慮使用(yòng)你熟悉的(de)語言來(lái)解決。這(zhè)樣就可(kě)能造成一些浪費和(hé)性能比較差的(de)情況。比如:計算(suàn)平均值的(de)時(shí)候不适用(yòng)MySQL原生的(de)AVG()方法,而是用(yòng)PHP将所有值循環一遍然後累加計算(suàn)平均值。
另外還(hái)要注意SQL查詢中的(de)PHP循環。通(tōng)常,在取得(de)所有結果之後再用(yòng)PHP來(lái)循環的(de)效率更高(gāo)。
一般在處理(lǐ)大(dà)量數據的(de)時(shí)候使用(yòng)強有力的(de)數據庫方法,更能提高(gāo)效率。
6.不優化(huà)查詢
99%的(de)PHP性能問題都是數據庫造成的(de),一條糟糕的(de)SQL語句可(kě)能讓你的(de)整個(gè)程序都非常慢(màn)。MySQL的(de)EXPLAIN statement,Query Profiler,many other tools的(de)這(zhè)些工具可(kě)以幫你找出那些調皮的(de)SELECT。
7.使用(yòng)錯誤的(de)數據類型
MySQL提供一系列數字、字符串、時(shí)間等的(de)數據類型。如果你想存儲日期,那麽就是用(yòng)DATE或者DATETIME類型,使用(yòng)整形或者字符串會讓事情更加複雜(zá)。
有時(shí)候你想用(yòng)自己定義的(de)數據類型,例如,使用(yòng)字符串存儲序列化(huà)的(de)PHP對(duì)象。數據庫的(de)添加可(kě)能很容易,但是這(zhè)樣的(de)話(huà),MySQL就會變得(de)很笨重,而且以後可(kě)能導緻一些問題。
8.在SELECT查詢中使用(yòng)*
不要使用(yòng)*在表中返回所有的(de)字段,這(zhè)會非常的(de)慢(màn)。你隻需要取出你需要的(de)數據字段。如果你需要取出所有的(de)字段,那麽可(kě)能你的(de)表需要更改了(le)。
9.索引不足或者過度索引
一般來(lái)說,應該索引出現在SELECT語句中WHERE後面所有的(de)字段。
例如,假如我們的(de)用(yòng)戶表有一個(gè)數字的(de)ID(主鍵)和(hé)email地址。登錄之後,MySQL應該通(tōng)過email找到相應的(de)ID。通(tōng)過索引,MySQL可(kě)以通(tōng)過搜索算(suàn)法很快(kuài)的(de)定位email。如果沒有索引,MySQL就需要檢查每一項記錄直到找到。
這(zhè)樣的(de)話(huà),你可(kě)能想給每一個(gè)字段都添加索引,但是這(zhè)樣做(zuò)的(de)後果就是在你更新或者添加的(de)時(shí)候,索引就會重新做(zuò)一遍,當數據量大(dà)的(de)時(shí)候,就會有性能問題。所以,隻在需要的(de)字段做(zuò)索引。
10.不備份
也(yě)許不常發生,但是數據庫損毀,硬盤壞了(le)、服務停止等等,這(zhè)些都會對(duì)數據造成災難性的(de)破壞。所以你一定要确保自動備份數據或者保存副本。
11.另外:不考慮其他(tā)數據庫
MySQL可(kě)能是PHP用(yòng)的(de)最多(duō)的(de)數據庫了(le),但是也(yě)不是唯一的(de)選擇。 PostgreSQL和(hé)Firebird也(yě)是競争者,他(tā)們都開源,而且不被某些公司所控制。微軟提供SQL Server Express,Oracle有10g Express,這(zhè)些企業級的(de)也(yě)有免費版。SQLite對(duì)于一些小型的(de)或者嵌入式應用(yòng)來(lái)說也(yě)是不錯的(de)選擇。
上一篇:IEEE幫你搞懂(dǒng)編程語言排名技術 [返回列表]
下(xià)一篇:C語言編程程序的(de)内存如何布局
- 全部評論(0)