1. 程式人生 > >Mysql通過Merge引擎進行分表

Mysql通過Merge引擎進行分表

Mysql通過Merge引擎進行分表

 

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

使用場景

  • 資料表記錄很大,單表記錄會超過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,分割為T1、T2、T3、T4,共4張小表,有兩種查詢維度A和B,A可以得到小表組合T1、T2和T3,B可以得到小表組合T2、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
  • 建立user1、user2、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表文件檢視是否關聯成功,如:

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

如何操作MERGE表的資料

  • 插入(INSERT)資料時,需要根據給定的路由策略將新資料分別插入不同的子表,此處採用對id進行模3計算(可能結果為0、1、2)來決定插入哪個子表。
  • 首先,應當獲取id,這個id應當在各個子表中都是唯一的,我們需要一張表來專門建立id,執行如


作者:Notonlyphper
連結:https://www.jianshu.com/p/9420a6a8ae2e
來源:簡書
簡書著作權歸作者所有,任何形式的轉載都請聯絡作者獲得授權並註明出處。