PHP+MySQL 千萬級資料處理案例(二) 分表的意義

huxiaobai_001發表於2020-04-14

前一篇部落格PHP+MySQL 千萬級資料處理案例(一)(分表)我們講過了分表的含義以及其中的方式之一,當然除了對主鍵取模,你也可以用hash來搞,這裡就不多講啦!今天我們說說分表的意義,意義,意義,意義是什麼???

關於分表:顧名思義就是一張資料量很大的表拆分成幾個表分別進行儲存。
我們先來大概瞭解以下一個資料庫執行SQL的過程:
接收到SQL –> 放入SQL執行佇列 –> 使用分析器分解SQL –> 按照分析結果進行資料的提取或者修改 –> 返回處理結果。在這個過程中一般比較花時間的是在佇列裡的等待時間和執行時間。歸根到底就是執行時間,執行時間減少了等待時間自然就變短了。
為了保證資料的完整性,資料庫有鎖定機制。MySQL中有表鎖定和行鎖定,MySQL中myisam儲存引擎是表鎖定,innodb儲存引擎是行鎖定。分為包含共享鎖和獨佔鎖兩種。獨佔鎖就是整個資料檔案歸一個執行緒所有,其他執行緒就必須等待。如果資料太多,一次執行的時間太長,特別是在鎖表的情況下,就會導致大量的其他SQL等待執行,嚴重影響系統的正常使用。
另外更新表資料時會導致索引更新,當單表資料量很大時這個過程比較耗時,這就是為什麼對大表進行新增操作會比較慢的原因。並且更新表資料會進行表級鎖或者行鎖,這樣就導致其他操作等待!
所以我們將大表拆分為多個字表,那麼在更新或者查詢資料的時候,壓力會分散到不同的表上。由於分表之後每個表的資料較小,不管是查詢還是更新都極大的提高了速度,即使出現最壞的“鎖表”的情況,那其他表還是可以並行使用。所以我們將大表拆分為多個字表,那麼在更新或者查詢資料的時候,壓力會分散到不同的表上。由於分表之後每個表的資料較小,不管是查詢還是更新都極大的提高了速度,即使出現最壞的“鎖表”的情況,那其他表還是可以並行使用。

分表的幾種常見策略:
(1)預先估計某個大表的資料量,按實際情況將其均分為固定數量表
根據分表演算法,將資料平均分散到不同的資料表中,常見處理方式有對自增id取模、對某個欄位進行hash。比如某系統使用者預計支援1億使用者數,分100個表儲存使用者資料,按照自增id的最後2位來分表,對100取模,那麼使用者資料表就是user_01~user_99。
(2)按時間拆分
對於那種根據時間增長較快的資料可以按時間拆分,根據業務實際情況按天、按月、按年等進行拆分。比如進銷存資料,我們可以按月分表,形如jxc_data_201201、jxc_data_201202
(3)按每個表固定記錄行數拆分
一般根據自增長ID拆表,每張表儲存指定數量的資料。一張表的資料行數到了指定數量,就自動儲存到新的表裡。
(4)將很久之前的資料遷移到一張歷史表
比如日誌記錄,一般只會查詢3個月之內的日誌,對於超過三個月的日誌記錄我們可以遷移到到遷移到另一張表中,比如log_history

本作品採用《CC 協議》,轉載必須註明作者和本文連結

胡軍

相關文章