Mysql的分割槽表
因hive資料在20180101 用sqoop同步到mysql的時候出錯,最終查詢原因發現是因為mysql中 對應的表的分割槽沒有建導致的,順帶研究下mysql的分割槽表
mysql的分割槽表的概述
mysql中分割槽表的定義:
將一個表或索引分解為多個更小、更可管理的部分,從邏輯上講,只有一個表或者索引,但是物理上這個表或者索引可能由數十個物理分割槽組成
資料庫表的分割槽一般有兩種:
水平分割槽:指將同一表中不同行的記錄分配到不同的物理檔案中
垂直分割槽:指將同一表中不同列的記錄分配到不同的物理檔案中
mysql 支援的全是前者。
mysql分割槽表的優勢(為什麼要分割槽)
對於大體量的資料能夠非常有效的提高查詢的速度(表非常大不能夠一次載入到記憶體中,表的組成由 大量的歷史資料+部分熱點資料)
降低管理和維護成本。對一個表中的每個獨立的分割槽都能夠進行獨立的操作(備份,恢復,匯出,查詢的優化…)
分割槽表可以避免某些特殊的瓶頸。InnoDB的單個索引的互斥訪問、ext3檔案系統的inode鎖競爭…
分割槽的策略
全量掃描資料:通過where條件語句來限制掃描的分割槽,需要注意的是,限制的分割槽的數量不能太多。
建立分割槽索引,設定熱點分割槽 將熱點資料設定到一個分割槽中,這樣能夠充分利用快取和索引,大幅提高資料查詢效率
ps:以上策略均以查詢得到過濾,丟掉額外的分割槽,分割槽本身不產生額外的代價為準則
分割槽表的型別
- range 分割槽(現在很少用,因為使用上有侷限在mysql5.5之後的話增加了Columns 分割槽,更加好用)
- list 分割槽 :類似於按RANGE分割槽,區別在於LIST分割槽是基於列值匹配一個離散值集合中的某個值來進行選擇。
- hash分割槽:根據使用者自定義的表示式的返回值來進行分割槽,返回值不能為負數
- key分割槽:根據MySQLS資料庫提供的雜湊函式來進行分割槽
【注:無論建立何種型別的分割槽,如果表中存在主鍵或唯一索引時,分割槽列必須是唯一索引的一個組成部分】
【MYSQL5.5之後,更好的支援】
RANGE分割槽和LIST分割槽只支援整數分割槽,從而導致需要額外的函式計算得到整數或者通過額外的轉換表來轉換為整數再分割槽的問題。Columns分割槽可以細分為RANGE Columns分割槽和LIST Columns分割槽,RANGE Columns分割槽和LIST Columns分割槽都支援整數、日期時間、字串三大資料型別
分割槽表相關的操作
#檢視當前資料庫是否支援分割槽
mysql>show variables like'%partition%';
#建立分割槽表
RANGE分割槽:
mysql>CREATETABLE`operation_log`(
->`id`int(11)unsignedNOT NULLAUTO_INCREMENT,
->`cid`mediumint(7)unsignedNOT NULL,
->`accountid`mediumint(8)NOT NULLDEFAULT'0',
->`flag`tinyint(1)unsignedNOT NULLDEFAULT'0',
->`addtime`int(11)unsignedNOT NULL,
->`device`tinyint(1)unsignedNOT NULLDEFAULT'1',
->PRIMARY KEY(`id`,`addtime`),
->KEY`idx_accountid_addtime`(`accountid`,`addtime`),
->KEY`idx_accountid_flag`(`accountid`,`flag`),
->)ENGINE=InnoDBAUTO_INCREMENT=50951039DEFAULTCHARSET=utf8COMMENT='操作記錄'
->/*!50100 PARTITION BY RANGE (addtime)
->(PARTITION `2013-05` VALUES LESS THAN (1370016000) ENGINE = InnoDB,
-> PARTITION `2013-06` VALUES LESS THAN (1372608000) ENGINE = InnoDB,
-> PARTITION `2013-07` VALUES LESS THAN (1375286400) ENGINE = InnoDB,
-> PARTITION `2013-08` VALUES LESS THAN (1377964800) ENGINE = InnoDB,
-> PARTITION `2013-09` VALUES LESS THAN MAXVALUE ENGINE = InnoDB) */;
#list分割槽
mysql> CREATE TABLE IF NOT EXISTS `list_part` (
-> `id` int(11) NOT NULL COMMENT '使用者ID',
-> `province_id` int(2) NOT NULL DEFAULT 0 COMMENT '省',
-> `name` varchar(50) NOT NULL DEFAULT '' COMMENT '名稱',
-> `sex` int(1) NOT NULL DEFAULT '0' COMMENT '0為男,1為女'
-> ) ENGINE=INNODB DEFAULT CHARSET=utf8
-> PARTITION BY LIST (province_id) (
-> PARTITION p0 VALUES IN (1,2,3,4,5,6,7,8),
-> PARTITION p1 VALUES IN (9,10,11,12,16,21),
-> PARTITION p2 VALUES IN (13,14,15,19),
-> PARTITION p3 VALUES IN (17,18,20,22,23,24)
-> );