2016年12月28日 星期三

網站被垃圾留言攻擊嗎?教你用 SQL 追殺 SPAM 垃圾留言!

這種 以己之矛攻己之盾的方法 真的是很高招,目前小惡魔網站應該還沒有被盯上的價值,不過先留下武功秘笈以備不時之需。

重點說明

DELETE FROM `nucleus_plugin_tb` WHERE block=1 and url IN ( SELECT url FROM `nucleus_plugin_tb` where block=1 group by url having count(*) > 10 )

首先作者的 blog 引文是要經過審核的,所以有 block=1 其他如我們一般所認知,但是...

MySQL 不能接受子查詢中用到同一張資料表,這是 MySQL 4.X 的 bug。

目前小惡魔網站用的是 MySQL 5.X 尚未測試是否有相同的問題,不過依然有解法如下

DELETE FROM `nucleus_plugin_tb` WHERE block=1 and url IN ( select url from (SELECT url FROM `nucleus_plugin_tb` where block=1 group by url having count(*) > 10 ) AS newtb )

順便偏題一下... o.O

這種自包查詢產生虛擬的 table 是我現在經常用到的技巧很實用,尤其像我們公司太多人在維護資料,所以產生很多資料分身,相同意義的欄位,不但分散在各個地方,而且欄位名稱各有巧妙,所以我會先寫好可以 reuse 的 SQL 類似如下:

insert into ...
from (select 'B121???' as bt_custid, '814' as bt_main_code) bt
  left join ...... on bt_custid = host.id
  left join ...... on bt_custid = z84.cust_idn and bt_main_code = z84.main_code
where ...

這是一個補資料(案件)的 SQL 因為每次補充來源不一樣 所以只要在 from (...) 之內改變一下,其餘的 SQL 都可以不變
採取這個技巧 就可以省去來源不一樣時,卻使用到相同的性質欄位,而導致 join 和 insert into 之後的語法可能要跟著改的麻煩。

不過查詢裡包子查詢是要很小心使用的,必須確認未來資料增長後仍不影響效能,否則恐怕會種下一個很難察覺的問題,真的要謹慎考慮!

轉載自:藍色小惡魔 - 魔窟《SQL》

沒有留言:

張貼留言