Mysql經過Merge引擎進行分表

Mysql經過Merge引擎進行分表

 

轉載: https://www.jianshu.com/p/9420a6a8ae2ejavascript

          https://www.cnblogs.com/xbq8080/p/6628034.htmlphp

使用場景

  • 數據表記錄很大,單表記錄會超過1000W,好比用戶表等。

測試環境

  • Mysql5.7

注意

分表的id不能是自增(auto increment)的; 分表必須使用MyISAM存儲引擎; 每一個分表的表結構必須相同; MySQL必須具備存儲分表數據文件和索引文件的目錄的讀寫權限; 必須啓用MySQL的符號連接支持功能。 總表的表結構必須與各個分表相同; 總表必須使用MRG_MyISAM存儲引擎; 總表不會建立任何數據文件和索引文件; MRG文件存儲總表須要映射的子表的表名; 總表自己不存儲任何數據和索引; INSERT_METHOD須要設置爲NO,或者不配置; 總表的id不能是自增(auto increment)的。 

MERGE分表的優勢

  • MERGE分表能夠解決下面的問題:
適用於存儲日誌數據。例如,能夠將不一樣月份的數據存入不一樣的表,而後使用myisampack工具壓縮數據,最後經過一張MERGE表來查詢這些數據。

能夠得到更快的速度。能夠根據某種指標,將一張只讀的大表分割成若干張小表,而後將這些小表分別放在不一樣的磁盤上存儲。當須要讀取數據時,MERGE表能夠將這些小表的數據組織起來,就好像使用先前的大表同樣,可是速度會快不少。

能夠提升搜索效率。能夠根據某種指標將一張只讀的大數據表分割爲若干個小表,而後根據不一樣的查詢維度,能夠獲得若干種小表的組合,而後再爲這些組合分別建立不一樣的MERGE表。例如,有一張只讀的大數據表T,分割爲T一、T二、T三、T4,共4張小表,有兩種查詢維度A和B,A能夠獲得小表組合T一、T2和T3,B能夠獲得小表組合T二、T3和T4,分別爲A和B建立兩個MERGE表,也就是M1和M2,這兩個MERGE表分別關聯的小表是存在交疊的。

能夠更加有效的修復表。修復單個的小表要比修復大數據表更加容易。

多個子表映射至一個總表的速度極快。由於MERGE表自己不會存儲和維護任何索引,索引都是由各個關聯的子表存儲和維護的,因此建立和從新映射MERGE表的速度很是快。

不受操做系統的文件大小限制。單個表會受到文件大小的限制,可是拆分紅多個表,則能夠無限擴容。

MERGE表還能夠用來給單個表建立別名,而且幾乎不會影響性能。

MERGE分表的問題

總表(MERGE表)必須使用MRG_MyISAM存儲引擎,子表必須使用MyISAM存儲引擎,不可避免會受到MyISAM存儲引擎的限制。

MERGE表不能使用某些MyISAM特性。例如,雖然能夠爲子表建立全文索引,可是卻不能使用全文索引,經過MERGE表查詢數據。

MERGE表會使用更多的文件描述符。若是有10個客戶端使用1張MERGE表,那麼就須要消耗(10×10)+10個文件描述符(其中,10個客戶端分別有10個數據文件描述符,而且會共享使用10個索引文件描述符)。 若使用ALTER TABLE語句修改總表的存儲引擎,那麼會當即丟失總表和子表的映射關係,而且會將全部子表的數據拷貝至修改後的新表。 總表和子表的主鍵都不能使用自動增加(auto increment)。 子表之間不能保證惟一鍵約束,只能保證單個子表內部的惟一性約束。 因爲不能保證惟一鍵約束,致使REPLACE語句的行爲會不可預期,INSERT ... ON DUPLICATE KEY UPDATE語句也有相似問題。所以,只能使用路由策略,對子表使用這些語句,而不能對總表使用。 子表不支持分區(Partition)。 當正在使用總表時,不能對任何子表執行ANALYZE TABLE、REPAIR TABLE、OPTIMIZE TABLE、ALTER TABLE、DROP TABLE、DELETE或TRUNCATE TABLE語句,不然會致使不可預期的結果。 總表和子表的表結構必須徹底一致。 總表能夠映射的全部子表的總行數上限爲 264 行。 不支持INSERT DELAYED語句。 

創建數據庫

CREATE database `test` DEFAULT CHARACTER SET utf8 ; 

創建子表

  • 分表必須使用MyISAM存儲引擎,而MyISAM表的數據文件(.MYD文件)和索引文件(.MYI文件)是能夠分散在不一樣的磁盤或目錄上存儲的。
  • 建立數據表的時候能夠制定存儲目錄,如:指定 DATA DIRECTORY = '/home/user3' INDEX DIRECTORY = '/home/user3';
  • 在Shell中執行如下命令,建立存儲子表數據和索引的目錄:
# 建立存儲user1表數據和索引的目錄 mkdir -p /home/user1 chown -R mysql:mysql /home/user1 # 建立存儲user2表數據和索引的目錄 mkdir -p /home/user2 chown -R mysql:mysql /home/user2 # 建立存儲user3表數據和索引的目錄 mkdir -p /home/user3 chown -R mysql:mysql /home/user3 
  • 啓用MySQL的have_symlink選項,使得MySQL支持符號連接,不然就不能指定MyISAM表的數據文件和索引文件的存儲路徑。在Shell中執行如下命令,編輯my.cnf文件:
vi /usr/local/MySQL/etc/my.cnf
  • 在my.cnf文件的[mysqld]分段中添加:
symbolic-links
  • 保存my.cnf文件以後,從新啓動mysql服務:
service mysqld restart
  • 建立user一、user二、user3分表,執行如下SQL:
CREATE TABLE `user1` ( `id` INT NOT NULL, `user_name` VARCHAR(45) NOT NULL, `password` VARCHAR(45) NOT NULL, `create_time` TIMESTAMP NULL, `update_time` TIMESTAMP NULL, PRIMARY KEY (`id`), KEY `user_name` (`user_name`), KEY `create_time` (`create_time`) )ENGINE = MyISAM; CREATE TABLE `user2` like user1; CREATE TABLE `user3` like user1; 
  • 創建user總表
CREATE TABLE `users` ( `id` INT NOT NULL, `user_name` VARCHAR(45) NOT NULL, `password` VARCHAR(45) NOT NULL, `create_time` TIMESTAMP NULL, `update_time` TIMESTAMP NULL, PRIMARY KEY (`id`), KEY `user_name` (`user_name`), KEY `create_time` (`create_time`) )ENGINE = MERGE UNION = (`user1`,`user2`,`user3`); 
  • or
CREATE TABLE users like user1;
ALTER TABLE users ENGINE=MERGE UNION(`user1`,`user2`,`user3`) insert_method=no; 

可經過查看users表文件查看是否關聯成功,如:html

cat /var/lib/mysql/test/users.MRG 

如何操做MERGE表的數據

  • 插入(INSERT)數據時,須要根據給定的路由策略將新數據分別插入不一樣的子表,此處採用對id進行模3計算(可能結果爲0、一、2)來決定插入哪一個子表。
  • 首先,應當獲取id,這個id應當在各個子表中都是惟一的,咱們須要一張表來專門建立id,執行如
做者:Notonlyphper 連接:https://www.jianshu.com/p/9420a6a8ae2e 來源:簡書 簡書著做權歸做者全部,任何形式的轉載都請聯繫做者得到受權並註明出處。
相關文章
相關標籤/搜索