首頁  >  文章  >  後端開發  >  mysql操作類,v0.2,增加應對大數據量的一些解決方案

mysql操作類,v0.2,增加應對大數據量的一些解決方案

WBOY
WBOY原創
2016-07-25 09:06:191016瀏覽
複製代碼
/*mysql 簡單類 by joffe q89949401 圍脖@狂code詩人; 本類別全靜態 使用的時候直接include後 用mysql::方法()名即可 由於類別在php5裡面全域可視,所以不必擔心變數範圍的問題.如果有什麼意見 請圍脖私訊||qq郵件; 目前沒有與預存程序有關的方法,當然預存程序一般是創建資料庫的時候做的. config檔需要設定以下常數資訊: LIB:類存放位置 DEBUG:是否開啟debug(如果開啟會輸出錯誤訊息追蹤) TB_EX:資料庫表前綴;

增加了select del update insert big_select big_del函數

*/
  1. /*mysql 簡單類別by joffe q89949401 圍脖>/*mysql 簡單類別by joffe q89949401 圍脖@狂code詩人;
  2. 本類全靜態使用的時候直接include後用mysql::@狂code詩人;
  3. 本類全靜態使用的時候直接用mysql::@方法狂code方法()名即可由於類別在php5裡面全局可視,所以不必擔心變數範圍的問題.如果有什麼意見請圍脖私訊||qq郵件;
  4. 目前沒有與預存程序有關的方法,當然預存程序一般是建立資料庫的時候做的.
  5. config檔需要設定以下常數資訊:
  6. LIB:類別存放位置
  7. DEBUG:是否開啟debug(如果開啟會輸出錯誤訊息追蹤)
  8. TB_EX:資料庫錶字首;
  9. */
  10. defined('LIB') 或 die('Missing config!!');
  11. final class mysql {
  12. /**
  13. * 查詢總數
  14. *
  15. * @var int
  16. */
  17. publicsql {
  18. /**
  19. * 連接句柄
  20. *
  21. * @var object
  22. */
  23. public static $querynum = 0;
  24. /**
  25. * 建構子
  26. *
  27. * @param string $dbhost 主機名稱
  28. * @param string $dbuser 使用者
  29. * @param string $dbpw 密碼
  30. @param string $資料庫名稱
  31. * @param int $pconnect 是否持續連線
  32. */
  33. public static $link;
  34. /*
  35. 表前綴
  36. @var string 下列方法需要在設定檔中設定TB_EX作為表的前綴
  37. */
  38. static function add_ex($tb){
  39. return TB_EX.$tb_ex.$tb;
  40. }
  41. /*mysql資料庫是否使用嚴格的類型(mysql類型沒開啟自動轉換)預設為false,表示mysql有開啟類型轉換,這個變數目前只要是用於insert函數的單引號在沒有自動轉換的mysql裡面的問題,可能將來會增加相關函數
  42. */
  43. public static $is_type_tight=false;
  44. /**
  45. * 選擇資料庫
  46. *
  47. * @param string $dbname
  48. * @return
  49. */
  50. static function connent($dbhost, $dbuser, $dbpw, $dbname = " ",$dbcharset, $pconnect = 0) {
  51. if($pconnect) {
  52. if(!self::$link = @mysql_pconnect($dbhost, $dbuser, $dbpw)) {
  53. self ::halt("Can not connect to MySQL server");
  54. }
  55. } else {
  56. if(!self::$link = @mysql_connect($dbhost, $dbuser, $dbpw)) {
  57. self::halt("Can not connect to MySQL server");
  58. }
  59. }
  60. if(self::version() > "4.1") {
  61. if($dbcharset ) {
  62. mysql_query("SET character_set_connection={$dbcharset}, character_set_results=$dbcharset, character_set_client=binary", self::$link);
  63. } 5.0.1") {
  64. mysql_query("SET sql_mode=''", self::$link);
  65. }
  66. }
  67. if($dbname) {
  68. mysql_select_db($dbname , self::$link);
  69. }
  70. }
  71. /**
  72. * 取出結果集中一筆記錄
  73. *
  74. * @param object $query
  75. * @param int $result_type
  76. * @return array
  77. */
  78. static function select_db($dbname) {
  79. ::return mysql_select_db($dbname, self $link);
  80. }
  81. /**
  82. * QuerySQL
  83. *
  84. * @param string $sql
  85. * @param string $type
  86. * @return object
  87. */
  88. static function fetch_array($query, $result_type = MYSQL_ASSOC) { //預設只取關聯數組不取數字數組.
  89. return mysql_fetch_array($query, $result_type);
  90. }
  91. /**
  92. * 取影響條數
  93. *
  94. * @return int
  95. */
  96. static function query($sql, $type = "") {
  97. $func = $type == "UNBUFFERED" && @function_exists("mysql_unbuffered_query") ?
  98. "mysql_unbuffered_query" : "mysql_query";
  99. if(!($query = $func($link($link)($link) ) && $type != "SILENT") {
  100. self::halt("MySQL Query Error", $sql);
  101. }
  102. self::$querynum++;
  103. return $query;
  104. }
  105. /**
  106. * 回傳錯誤訊息
  107. *
  108. * @return array
  109. */
  110. static function affected_rows() {
  111. return mysql_affected_rows(self::$link);
  112. }
  113. ** /
  114. static function error() {
  115. return ((self::$link) ? mysql_error(self::$link) : mysql_error());
  116. }
  117. /**
  118. * 回傳錯誤碼
  119. *
  120. * @return int
  121. */
  122. static function errno() {
  123. return intval((self::$link) ? mysql_errno(self::$link) : mysql_errno());
  124. }
  125. /**
  126. * 回傳查詢結果
  127. *
  128. * @param object $query
  129. * @param string $row
  130. * @return mixed
  131. */
  132. static function result($query, $row,$flname=0) {
  133. $query = @mysql_result($query, $row,$flname);
  134. return $query;
  135. }
  136. /**
  137. * 結果條數
  138. *
  139. * @param object $query
  140. * @return int
  141. */
  142. static function num_rows($query) {
  143. $query = mysql_num_rows($query);
  144. return $query;
  145. }
  146. /**
  147. * 取總欄位
  148. *
  149. * @param object $query
  150. * @return int
  151. */
  152. static function num_fields($query) {
  153. return mysql_num_fields($query);
  154. }
  155. /**
  156. * 釋放結果集
  157. *
  158. * @param object $query
  159. * @return bool
  160. */ staticunction free_result($query) { return @mysql_free_result($query); }
  161. /**
  162. * 回傳自增ID
  163. *
  164. * @return int
  165. */
  166. 靜態函數insert_id() {
  167. return ($id = mysql_insert_id(self::$link)) >= 0 ? $id : self::$result( self::$query("SELECT last_insert_id()"), 0);
  168. }
  169. /**
  170. * 從結果集中取得一行作為枚舉數組
  171. *
  172. * @param object $query
  173. * @return array
  174. */
  175. 靜態函數fetch_row($query) {
  176. $query = mysql_fetch_row ($query);
  177. 回傳$query;
  178. }
  179. /**
  180. * 從結果集中取得列資訊並作為物件回傳
  181. *
  182. * @param object $query
  183. * @return object
  184. */
  185. 靜態函數fetch_fields($query) {
  186. return mysql_fetch_field($query);
  187. }
  188. 靜態函式select_affectedt_rows($rs){
  189. return mysql_affected_rows($rs,self::$link);
  190. }
  191. /**
  192. * 回傳mysql版本
  193. *
  194. * @return string
  195. */
  196. 靜態函式version() {
  197. return mysql_get_server_info(self::$link);
  198. }
  199. /**
  200. * 關閉連線
  201. *
  202. * @return bool
  203. */
  204. 靜態函式close() {
  205. return mysql_close(self::$link);
  206. }
  207. /**
  208. * 輸出錯誤訊息
  209. *
  210. * @param string $message
  211. * @param string $sql
  212. */
  213. 靜態函數halt($message = "", $sql = "") {
  214. @header( "內容類型:text/html; charset=utf-8");
  215. if (DEBUG==1){
  216. $debug = debug_backtrace();
  217. echo $message 。 “rn
    SQL-->”。 $sql."rn
    ERROR_MESSAGE-->".self::error().
  218. "rn
    --------------調試- --- ----------rn
    ";
  219. self::echoarray($debug);
  220. echo "rn
    ------ ----- --調試結束----------------";
  221. }else{
  222. echo 'SQL 錯誤';
  223. }
  224. @self: :rollback();
  225. exit;
  226. }
  227. ///// ////////////////////////以下是擴充的sql方法.//////
  228. /* 把佇列依照key value value的對應關係插入資料表表中
  229. table要插入的資料表
  230. 要注意這些擴充方法是沒自己給表有加外接的。
  231. */
  232. static function insert($table,$array ){
  233. $temp="";$temp2='';
  234. foreach($array as $key=>$value){
  235. if(self::$is_type_tight){
  236. if (is_string($value)){
  237. $temp .="$key,";$temp2 .="'$value',";
  238. }elseif(is_int($value||is_null($value)) ||is_float($value))){
  239. $value+=0;
  240. $temp .="$key,";$temp2 .="'$value',";
  241. }
  242. }else{
  243. $temp .="$key,";$temp2 .="'$value',";
  244. }
  245. }
  246. $temp = substr($temp,0,strlen ($temp)-1);
  247. $temp2 = substr($temp2,0,strlen($temp2)-1);
  248. $sql = "插入$table ($temp) VALUE( $temp2)";
  249. return self::query($sql);
  250. }
  251. 靜態函數del ($table,$where){
  252. $sql = "刪除FROM {$table} where {$where}";
  253. return self::query($sql);
  254. }
  255. 靜態函數update($table,$array,$where){
  256. foreach ($array as $key=>$value){
  257. $temp .= "$key='$value',";
  258. }
  259. $temp = substr($temp,0 ,strlen($temp)-1);
  260. $sql = "update {$table} set ($temp) where {$where} ";
  261. return self::query($sql);
  262. }
  263. /*進行資料庫查詢選擇參數不定
  264. 參數說明:所有參數必須是字串
  265. 第一個參數必須是表名;
  266. 從第二個參數開始,
  267. 如果是寫上"where:XXX" 則認為是where條件;
  268. 如果寫上"xxx" 則認為是鍵值
  269. 如果寫上"by:XXX" 則認為是排序
  270. 如果寫上"limit:xxx,xxx" 則認為是分頁
  271. #參數不正確則傳回false; 成功回傳查詢後的佇列;
  272. */
  273. static function select(){
  274. $numargs = func_num_args();//取得參數個數;
  275. $where = "";$key ="";$limit=" ";$by="";
  276. if($numargs==0){return false;}
  277. //echo $numargs;
  278. if($numargs>= 2){
  279. $arg_list = func_get_args();
  280. $table = $arg_list[0];
  281. unset($arg_list[0]);
  282. // print_r($arg_list);
  283. foreach($arg_list as $k =>$value){
  284. if(preg_match("#^(where:)w#",$value)){
  285. $temp =explode(":", $value);
  286. $where = "WHERE {$temp[1]} " ;
  287. }elseif(preg_match("#^by:w#",$value)){
  288. $temp = 爆炸(":",$value);
  289. $by = "依{$temp[1]} 排序" ;
  290. }elseif(preg_match("#^limit:w#",$value)){
  291. $temp =explode(": ",$value);
  292. $limit = "limit {$temp[1]}";
  293. }else{
  294. $key .= "$value," ;
  295. }
  296. }
  297. if($key==""){
  298. $key = "*";
  299. }else{
  300. $key =substr($鍵,0,strlen($key) -1);
  301. }
  302. $sql_base="SELECT $key FROM $table";
  303. }
  304. if(!empty($where)){
  305. $sql_base .= " $where" ;
  306. }
  307. if(!empty($by)){
  308. $sql_base .= " $by";
  309. }
  310. if(!empty($limit)){
  311. $sql_base .= " $limit";
  312. }
  313. //echo $sql_base;
  314. //echo $by ;
  315. $rs = self::query($sql_base);
  316. $re=array();
  317. if(self::num_rows($rs)>=1){
  318. while($info = self : :fetch_array($rs)){
  319. $re[]=$info;
  320. }
  321. }
  322. self::free_result($rs);
  323. return $re;
  324. }
  325. /*回滾事務*/
  326. static function rollback(){
  327. self::query('rollback');
  328. }
  329. /*開始事務* /
  330. static function begin(){
  331. self::query('SET AUTOCOMMIT =0'); //失效自動提交;
  332. self::query('BEGIN') ;//開始一個事務;
  333. }
  334. /*提交事務*/
  335. static function commit() {
  336. self::query('commit');
  337. }
  338. 靜態函數echoarray($array){
  339. foreach($array as $k=>$v ){
  340. if(is_array($v)){
  341. if(is_array($v)){
  342. echo "
    ------------- -------------------
    ";
  343. self::echoarray($v);
  344. }
  345. }else{
  346. if($k==='line')
  347. echo "$k -> " .$v." ";
  348. else
  349. echo "$k -> " .$v." ";
  350. }
  351. }
  352. }
  353. function get_server_info(){
  354. return mysql_get_server_info() ;
  355. }
  356. //是下面應付大數據的表的最佳化查詢
  357. //是下面應付大數據的表的最佳化查詢
  358. big_select 適合大規模的查詢,利用覆蓋索引實現忽略的偏移活動窗口,令查詢在覆蓋索引上偏移而不是在所有數據上,減少msql在數據上檢查,再把其他數據加入進來這樣更高效。但對於小規模數據,這種查詢反而相反地增加複雜度,增加優化器壓力。 舉個例子,如果你是limit 10000,20;mysql會先查出10020條資料重新丟棄10000這樣的操作成本非常大,利用這個函數可以有效提升效率,但如果是limit 20,那就會比直接select慢了一些
  359. @table string要查詢的表如"table1"
  360. @keys string要查詢的鍵值,多個鍵值用","分割如" key1,key2,key3"結束清晰", "學少用"*"且一些關鍵字請加上`;
  361. @Index string 主索引鍵或唯一索引鍵名,只需要一個如"id";
  362. @pagesize int 分頁大小,必須,你不會想那麼多資料全部出來吧
  363. @pageNo 頁碼,從0開始
  364. @orderby string 排序如"id desc";可空,但不建議空
  365. @where string 條件如"date >122424533"可空
  366. #回傳記憶體
  367. */
  368. static function big_select($table,$keys,$index,$pagesize,$pageNo,$ orderby=NULL,$where=NULL){
  369. $start=$pageNo*$pagesize;
  370. if($where){
  371. $sqlIndex="從{$table} 選擇{$index} where { $where}";
  372. }else {
  373. $sqlIndex="從{$table} 選擇{$index}";
  374. }
  375. if($orderby){
  376. $sqlIndex .= " ORDER BY {$orderby} 限制$start ,$pagesize";
  377. }else{
  378. $sqlIndex .=" ORDER BY Limit $start,$pagesize";
  379. }
  380. $sql = "從{$table} INNER JOIN 選擇$keys ({$sqlIndex} ) AS lim USING({$index})";
  381. $rs = self::query($sql);
  382. $re=array();
  383. if(self: :num_rows($rs)>=1){
  384. while($info = self::fetch_array($rs)){
  385. $re[]=$info;
  386. }
  387. }
  388. self::free_result($rs);
  389. return $re;
  390. }
  391. /* 如果一個很大的資料(預計最大萬行)刪除的工作週期會比較長,會長時間鎖住不應該鎖住的表或行,令一些不該打斷的數據被打斷方法如下是把一個大的sql任務分小(分成一次5000行)但次操作可能會造成刪除空白期間插入了新的數據,而新的數據可能會因滿足條件而被刪除。本方法很容易因為超時而失敗。
  392. @table string 要刪除資料的表名
  393. @where string 條件可省略
  394. #int 刪除掉的行數
  395. */
  396. static function big_del($table,$where){
  397. set_time_limit(0);
  398. $sql="delete from {$table}其中{$where} 限制5000";
  399. $rows = 0;
  400. $eff=0;
  401. do {
  402. self::query($sql);
  403. $rows=self: :affected_rows();
  404. $eff += $rows;
  405. }while($rows>0);
  406. return $eff;
  407. }
  408. }
?>


陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn