app后端設計-- 數據庫分表


當項目上線后,隨着用戶的增長,有些數據表的規模會以幾何級增長,當數據達到一定規模的時候(例如100萬條),查詢,讀取性能就下降得很厲害,這時,我們就要考慮分表。

 

   更新表數據時會導致索引更新,當單表數據量很大時這個過程比較耗時,這就是為什么對大表進行新增操作會比較慢的原因,並且更新表數據會進行表級鎖或者行鎖,這樣就導致其他操作等待。

 

    所以我們將大表拆分為多個子表,那么在更新或者查詢數據的時候,壓力會分散到不同的表上。由於分表之后每個表的數據較小,不管是查詢還是更新都極大的提高了速度,即使出現最壞的“鎖表”的情況,那其他表還是可以並行使用。

 

1.分表的策略

 

分表有多種策略:

 

(1)按用戶id分表,例如id為1-10000在表1,id為10001-20000在表2

(2)插入的時間分表

(3)按每個表固定記錄行數拆分

 

    在項目,由於這個表是保存用戶的通訊錄,為了保證一個用戶的所有通訊錄數據都保存在同一個表,選擇的分表方式就是(1),按用戶id分表。

 

2. 分表策略確定下來了,還有一個非常嚴重的問題,因為現在用戶的數據都分散在不同的表中,之前的業務功能如何保證呢?比如說我要插入一條記錄、更新一條記錄、刪除一條記錄、查詢統計數據,現在要怎么處理呢?

 

    如果分表的存儲引擎是MyISAM,這里有一種很簡單的處理方法。利用merge存儲引擎將拆分的表合並成一張表。當然了,如果使用InnoDB,也能通過alter table命令把InnoDB變為MyISAM。

 

     MERGE存儲引擎可以將N個子表聯合在一起,看成是一個整表,實際上還是N個真實的子表。

 

    當分表的時候,還要一個問題,因為我們是在線上項目中分表的,需要考慮怎么樣使分表的操作對用戶的影響最少。

 

3. 一個例子

 

    假設有表contact,存儲了9000個用戶的通訊錄數據,平均一個用戶有聯系人100個,那么這個表的規模就達到了90萬條數據,我們需要對這個表分表。

 

    下面的腳本演示了怎么在不關閉MySQL服務的情況下對contact 分表

-- ----------------------------  -- 創建根據原來的表格式創建一個臨時表,並把存儲引擎改為MYISAM  -- --------------------------- 
CREATE TABLE contact_temp LIKE contact; ALTER TABLE contact_temp ENGINE = MYISAM CHARACTER SET utf8 COLLATE utf8_general_ci ; -- ----------------------------  -- 創建分表contact_temp1,contact_temp2  -- --------------------------- 
CREATE TABLE contact_temp1 LIKE contact_temp; CREATE TABLE contact_temp2 LIKE contact_temp; -- ----------------------------  -- 按用戶id分表,把id<5000 保存在表1,id>=5000 and id<10000 保存在表2,  -- ---------------------------- 
INSERT INTO contact_temp1 SELECT * FROM contact where uid<5000; INSERT INTO contact_temp2 SELECT * FROM contact where uid>=5000 and uid<10000; -- ----------------------------  -- 把原來的表改名,因為在mysql中不能有重復的表明,這樣子最終創建的MERGE引擎的表就能使用原來的表名  -- ---------------------------- 
RENAME TABLE contact TO contact_bak; CREATE TABLE contact LIKE contact_temp; -- ----------------------------  -- 先把原來刪除表上的主鍵的自增屬性去掉,再刪除主鍵  -- ---------------------------- 
ALTER TABLE contact CHANGE `id` `id`  int(11); ALTER TABLE contact DROP PRIMARY KEY; -- ----------------------------  -- 把表的存儲引擎改為MERGE  -- ---------------------------- 
ALTER TABLE contact  ENGINE=MERGE UNION=(contact_temp1,contact_temp2) INSERT_METHOD=LAST; -- ----------------------------  -- 刪除所有的臨時表  -- ---------------------------- 
drop TABLE contact_bak; drop TABLE contact_temp;  




免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM