從 5 月份到 6 月份這段期間面試了好多個 PHP 程式設計師 , 包括也曾開職缺面試資訊主管
我都會問一個問題 , SQL Injection 怎麼防 ?
我說真的 , 大概面試了 10 來位 , 沒有一個人能夠脫口而出 , 不知道 SQL Injection 的程式設計師不會就算了 , 知道的人居然沒有一個人知道 PHP 原本就有功能可以過濾掉特殊字元 , 甚至還會回答用 str_replace 方法來過濾 , 所以我很想給看到這篇的人知道
如果你是用 mysql function , 那就是用 mysql_real_escape_string 去過濾
如果你是用 PDO , 就是用 bind value 作法
例如
1
2
3
4
5
| $sql = "SELECT * FROM users WHERE user_id=?";
$sth = $pdo->prepare($sql);
$sth->execute( array($user_id) ); |
其實我是已經受夠了 !! 不知道是台灣的書籍太爛 , 還是學校裡面老師教的太爛 , 這種最簡單的防止方式居然都沒人知道 ?
閱讀全文…
假設 , 我們有個 Table 叫 test , 有 20 萬筆記錄 , test 有 20 個欄位好了 , 其中有一個欄位 post_time 有建立索引可以排序用的 , 而有個主鍵 id
下一道指令
SELECT * FROM test ORDER BY post_time DESC LIMIT 150000,10 |
這道指令看似簡單 , 理論上應該跑很快 ~ 實際上卻不然 , 也許跑上 20 秒 , 因為這牽扯到 MySQL Server 的 sort buffer 大小 , 因為這道指令可能會因為 buffer 不足而改用 disk 作 sort , 這樣就很慢了
這時候就要搬出 subquery 了 , 怎麼作 ? 看看下面
SELECT * FROM test AS t
INNER JOIN ( SELECT id FROM test ORDER BY post_time DESC LIMIT 15000,10 ) AS s
ON t.id=s.id |
我相信 , 這道指令應該 1 秒都不用
為何會如此呢 ?
因為我們在 subquery 中只有抓 id , 這樣 mysql 就只需要少量記憶體就可以存放資料列進行排序 , 原始的作法就是每一列有多少資料 , mysql 就必須分配多少記憶體 , 如果資料數太大 , 記憶體不夠分配 , 自然就是用 disk 了
但如果我們要抓的資料只是前面幾筆 , 例如 LIMIT 100,10 , 那麼原本的寫法會比較快 , 因此這可以在程式中判斷而交互使用兩種 QUERY 的方式
這一篇是記錄一下當 Mail Server 是採用 postfix + mysql 認證時 , 如何設定 RoundCube 的改密碼 plugin
平台是 CentOS 5.3 + mysql 5.1 + postfix_mysql + roundcube 0.3 stable
設定方法很簡單
先找到 roundcube 安裝目錄下的 plugins/password 這個目錄
把 config.inc.php.dist 改成 config.inc.php 或用複製成另一個新檔都可以 , 然後要修改 config.inc.php
我們必須先修改以下三個參數
- $rcmail_config['password_driver'] : 這個是設定密碼密碼認證的方式
- $rcmail_config['password_db_dsn'] : 這個是設定 posftix 認證的資料庫連接資訊(注意!不是roundcube資料庫喔)
- $rcmail_config['password_query'] : 這是設定修改密碼的 SQL Query
$rcmail_config['password_driver'] 必須設定為 sql , 才適用 mysql 的方式 , 例如
$rcmail_config['password_driver'] = 'sql'; |
$rcmail_config['password_db_dsn'] 的格式是 PEAR DSN 的格式 , 例如
$rcmail_config['password_db_dsn'] = 'mysql://postfix:1234@localhost/postfix'; |
閱讀全文…
這一篇是為了報答某論壇站長說若去澳門玩費用全免而寫的 .. 也要看我有沒有錢搭飛機去澳門 … 唉
mysqlftppc-bigram 是 MySQL 的 FullText Plugin , 是用 n-gram 演算法去斷詞因此得以支援中文全文索引 , 目前僅支援 myisam 表格 , 且中文索引的欄位必須為 utf-8 , 廢話不說以下就是安裝過程
平台 : CentOS 5.3 64bit
需要的相關件
-
MySQL 版本必須是 5.1 或以上
-
最新的 mysqlftppc-bigram , http://sourceforge.net/projects/mysqlftppc/
-
mysql-devel 套件 , 可先用 yum 先安裝好
-
libicu-devel 套件 , 要有這個才可以支援 UNICODE , 可先用 yum 先安裝好
閱讀全文…
似乎大家對 myisam 的初步認識就是很快 , 不支援 Transaction , 適合當小型快速的資料儲存 , 但我看很多論壇(包括我公司) , 一旦會員很多的時候 , 不管用多好的硬體 , 總是會常常有 Slow Query 出現 , 而且若網站的連接數量越多越容易出現 , 可是 CPU LOADING 用的卻不高
但可能自己把 Slow Query 拿來再執行的時候會覺得很快啊 …. 怎會這樣 ><
這應該要歸罪於 myisam 做任何的資料異動總是會 Table Lock , 因此常常在 phpmyadmin 中看看狀態 , 會發現很多 Table Lock Wait …
是的 , 該死的 Table Lock , 如果剛好有某一條連線所做的 INSERT/ UPDATE / DELETE 動作耗時 1 秒(也許等硬碟) , 那麼可能所有需要讀取該 Table 的人都要等 1 秒完才能讀取該 Table
既然如此 , InnoDB 理論上在較多人連線時後運行的穩定度會比較好 , 不知道我的推論是否正確
還記得以前我在互動王設計股票看盤的時候 , 每秒一直讀資料進來並且塞資料 , 而且 Client 端是一直連線在接收資料 , 是都沒發現甚麼 Table Lock Wait 的問題 , 當時我就是用 InnoDB , 也許真的 InnoDB 屬於 ROW Lock 層級真的比較適合大型網站
但這些也只是推斷 , 下一版的改版網站 , 大概就可以證明這件事情了
最近一直在那悶 , 為何 MySQL 在某些地方特別慢
舉例
1. 執行 SELECT count( … ) WHERE …. 這種命令 , 會非常慢
2. 執行 SELECT ….. ORDER BY key1,key2 這種命令 , 會非常慢
以上兩種應用情況會發生在資料筆數很多(超過百萬筆)的時候發生 , 在我現任職的公司機器上有 8G RAM 的情況下 , 各種 buffer 調很高一樣慢
由於公司是經營論壇 , 其實在資料的正確性上若不是一定要百分百正確 , 其實仔細研究一下 Discuz , Discuz 用了很多取巧的方式
例如我們要計算某個討論版有多少主題 , 如果真的去 SELECT count() … ,那真的會掛掉 , Discuz 的做法是 , 在表格 cdb_forums 中有另外一個欄位記錄有多少主題數 , 而不是真的去算
而 ORDER BY 的問題 , MySQL 的文件也有提到 , 如果要以兩個欄位排序 , 其實不會用到索引 , 所以都要盡量用取巧的方式 , 讓排序只用到一個 key
最近真的改公司的程式改到很煩 , 所以先記下這些問題 , 以後在規劃資料庫結構時 , 可以特別注意
MySQL 內建的 FullText Engine 不支援中文是眾所皆知的
在 5.0 版之後 , 有所謂的 plugin 功能 , 其他非官方的人可以寫 plugin 去加強 MySQL 功能
而在 FullText 的部分也有人去寫
例如 Spinx ( http://sphinxsearch.com/ ) : 這套號稱支援中文全文索引 , 支援 myisam 及 innodb , 不過我還沒試 , 但好像不是同步作索引
另外我要介紹一個網站 http://sourceforge.net/projects/mysqlftppc/
這裡面有很多種 FullText Plugin , 其中有個叫 bigram 的支援中文喔 , 必須在 mysql 5.1 版以上運作
比較麻煩的是 , 要自己編譯 , 我在 FreeBSD 及 Linux 上都可以正常跑
大概拿公司的數據 80 萬筆資料(原始資料用了200M空間) , 欄位是 TEXT 的資料來做全文搜尋字串"三國志" 好了, 大概花了 0.02 秒 , 如果用 LIKE %三國志% 的方式 , 會花上 0.7 秒 …. 這真的是太驚人的效能
但 bigram 有個缺點是 , 索引佔用的空間挺大的 , 所以空間要備足
由於這個 plugin 是即時的索引 , 所以一有資料新增 , 馬上就能搜尋 , 大家可以試試看喔
最新回應