• 表分區是將一個表的數據按照必定的規則水平劃分爲不一樣的邏輯塊,並分別進行物理存儲,這個規則就叫作分區函數,能夠有不一樣的分區規則mysql
• 經過show plugins語句查看當前MySQL是否支持表分區功能;5.7表分區功能默認開啓;算法
MySQL表分區介紹sql
• 當表中含有主鍵或惟一鍵時,則每一個被用做分區函數的字段必須是表中惟一鍵和主鍵的所有或一部分,不然就沒法建立分區表函數
例:優化
mysql> CREATE TABLE tnp (id INT NOT NULL AUTO_INCREMENT,ref BIGINT NOT NULL,name VARCHAR(255),PRIMARY KEY pk (id),UNIQUE KEY uk (ref) ) PARTITION BY RANGE (id) ( PARTITION p0 VALUES LESS THAN (6), PARTITION p1 VALUES LESS THAN (11));
ERROR 1503 (HY000): A UNIQUE INDEX must include all columns in the table's partitioning functionui
mysql> CREATE TABLE tnp (id INT NOT NULL AUTO_INCREMENT,ref BIGINT NOT NULL,name VARCHAR(255),PRIMARY KEY pk (id),UNIQUE KEY uk (ref) ) PARTITION BY RANGE (ref) ( PARTITION p0 VALUES LESS THHAN (6), PARTITION p1 VALUES LESS THAN (11));
ERROR 1503 (HY000): A PRIMARY KEY must include all columns in the table's partitioning functionspa
• 表分區的主要優點在於:
• 能夠容許在一個表裏存儲更多的數據,突破磁盤限制或者文件系統限制
• 對於從表裏將過時或歷史的數據移除在表分區很容易實現,只要將對應的分區移除便可
• 對某些查詢和修改語句來講,能夠自動將數據範圍縮小到一個或幾個表分區上,優化語句執行效率。並且能夠經過顯示指定表分區來執行語句unix
例:code
SELECT * FROM t PARTITION (p0,p1) WHERE c < 5;blog
mysql表分區類型
表分區類型分爲:
• RANGE表分區:範圍表分區,按照必定的範圍值來肯定每一個分區包含的數據
• LIST表分區:列表表分區,按照一個一個肯定的值來肯定每一個分區包含的數據
• HASH表分區:哈希表分區,按照一個自定義的函數返回值來肯定每一個分區包含的數據
• KEY表分區 :key表分區,與哈希表分區相似,只是用MySQL本身的HASH函數來肯定每一個分區包含的數據
RANGE表分區
• 範圍表分區,按照必定的範圍值來肯定每一個分區包含的數據,分區函數使用的字段必須只能是整數類型
• 分區的定義範圍必須是連續的,且不能有重疊部分,經過使用VALUES LESS THAN來定義分區範圍,表分區的範圍定義是從小到大定義的
例:
CREATE TABLE employees ( id INT NOT NULL, fname VARCHAR(30), lname VARCHAR(30), hired DATE NOT NULL DEFAULT '1970-01-01', separated DATE NOT NULL DEFAULT '9999-12-31', job_code INT NOT NULL, store_id INT NOT NULL )
PARTITION BY RANGE (store_id)
( PARTITION p0 VALUES LESS THAN (6), PARTITION p1 VALUES LESS THAN (11),
PARTITION p2 VALUES LESS THAN (16), PARTITION p3 VALUES LESS THAN (21),PARTITION p4 VALUES LESS THAN MAXVALUE);
• MAXVALUE關鍵詞的做用是表示可能的最大值,因此任何store_id>=21的數據都會被寫入到p4分區裏
• 對timestamp字段類型可使用的表達式目前僅有unix_timestamp,其餘的表達式都不容許
• 分區函數中也可使用表達式
LIST表分區
• 列表表分區,按照一個一個肯定的值來肯定每一個分區包含的數據
• 經過PARTITION BY LIST(expr)分區函數表達式必須返回整數,取值範圍經過VALUES IN (value_list)定義
例:
mysql> CREATE TABLE h2 (c1 INT, c2 INT )
PARTITION BY LIST(c1)
(PARTITION p0 VALUES IN (1, 4, 7),
PARTITION p1 VALUES IN (2, 5, 8));
• 對List表分區來講,沒有MAXVALUE特殊值,全部的可能取值都須要再VALUES IN中包含,若是沒有定義的值則會報錯
• 一樣,當有主鍵或者惟一鍵存在的狀況下,分區函數字段須要包含在主鍵或惟一鍵中
• 對range和list表分區來講,分區函數能夠包含多個字段
• 分區多字段函數所涉及的字段類型能夠包括:
• TINYINT, SMALLINT, MEDIUMINT, INT (INTEGER), and BIGINT. DATE and DATETIME. CHAR, VARCHAR, BINARY, and VARBINARY; 其餘的字段類型都不支持
• 範圍多字段分區函數與普通的範圍分區函數的區別在於:
a) 字段類型多樣化
b) 範圍多字段分區函數不支持表達式,只能用字段名
c) 範圍多字段分區函數支持一個或多個字段
哈希表分區
• 按照一個自定義的函數返回值來肯定每一個分區包含的數據,這個自定義函數也能夠僅僅是一個字段名字
• 經過PARTITION BY HASH (expr)子句來表達哈希表分區,其中的expr表達式必須返回一個整數,基於分區個數的取模(%)運算。根據餘數插入到指定的分區
• 對哈希表分區來講只須要定義分區的個數,其餘的事情由內部完成
例:
• CREATE TABLE t1 (col1 INT, col2 CHAR(5), col3 DATE) PARTITION BY HASH( YEAR(col3) ) PARTITIONS 4; ##不指定PARTITIONS默認爲1
key表分區
與哈希表分區相似,只不過哈希表分區依賴於自定義的函數,而key表分區的哈希算法是依賴MySQL自己
• CREATE TABLE ... PARTITION BY KEY ()建立key表分區,括號裏面能夠包含0個或者多個字段,所引用的字段必須是主鍵或者主鍵的一部分,若是括號裏面沒有字段,則表明使用主鍵 ###若是表中沒有主鍵但有唯一鍵,則使用唯一鍵,但唯一鍵必須定義爲not null,不然會報錯
MySQL表分區對Null值處理
不一樣的表分區對NULL值的處理方式不一樣
• 對範圍表分區來講,若是插入的是NULL值,則將數據放到最小的分區表裏
• 對list表分區來講,支持NULL值的惟一狀況就是某個分區的容許值中包含NULL
• 對哈希表分區和Key表分區來講,NULL值會被當成0值對待
MySQL表分區管理
刪除表分區
• 經過alter table命令能夠執行增長,刪除,從新定義,合併或者拆分表分區的管理動做
• 對範圍表分區和列表表分區來講,刪除一個表分區命令 ###刪除表分區的動做不光會把分區刪掉,也會把表分區裏原來的數據給刪除掉
例:
ALTER TABLE tablename DROP PARTITION 分區名稱;
增長表分區
• 在原分區上增長一個表分區能夠經過alter table … add partition語句來完成
• 但對範圍表分區來講,增長的表分區必須在尾部增長,在頭部或者在中間增長都會失敗;## 爲解決這個問題,可使用REORGANIZE命令:
ALTER TABLE members REORGANIZE PARTITION p0 INTO ( PARTITION n0 VALUES LESS THAN (1970), PARTITION n1 VALUES LESS THAN (1980) );
• 對列表表分區來講,只要新增長的分區對應的值在以前的表分區中沒有出現過,就能夠經過alter table… add partition來增長
其餘管理命令
• 當須要去除分區碎片是,能夠執行rebuild命令,至關於刪除數據以後從新插入
• ALTER TABLE t1 REBUILD PARTITION p0, p1;
• 也能夠執行OPTIMIZE命令回收分區中未使用的空間和從新獲取統計資料
• ALTER TABLE t1 OPTIMIZE PARTITION p0, p1;
• Analyzing partitions命令從新收集分區統計資料
• ALTER TABLE t1 ANALYZE PARTITION p3;
• Repairing partitions命令修復異常的分區
• ALTER TABLE t1 REPAIR PARTITION p0,p1;
• Checking partitions命令檢查分區中數據或者索引數據是否損壞
• ALTER TABLE t1 CHECK PARTITION p1;
• ALTER TABLE ... TRUNCATE PARTITION命令用來刪除分區中的全部數據
實際應用
項目需求:項目中按照時間劃分分區使用range分區方式(每週爲單位劃分一個分區)
1.分區表表結構
表結構定義略...
PARTITION BY RANGE (TO_DAYS(publishtime))
(PARTITION p20190102 VALUES LESS THAN (737427))
2.實現自動增加分區方式
經過mysql事件調度存儲過程來實現
具體SQL以下:
建立一個事件
CREATE DEFINER=`d5000`@`%` EVENT `Partition_base_data_event` ON SCHEDULE EVERY 7 DAY STARTS '2019-01-02 10:55:00' ON COMPLETION NOT PRESERVE ENABLE DO CALL create_partition_base_data()
建立存儲過程
CREATE DEFINER=`d5000`@`%` PROCEDURE `create_partition_base_data`() BEGIN SET @Max_date= DATE(DATE_ADD(NOW(), INTERVAL 1 DAY))+0; SET @s1=CONCAT('ALTER TABLE base_data ADD PARTITION (PARTITION p',@Max_date,' VALUES LESS THAN (TO_DAYS (''',DATE_ADD(@Max_date, INTERVAL 7 DAY),''')))'); SELECT @s1; PREPARE stmt2 FROM @s1; EXECUTE stmt2; DEALLOCATE PREPARE stmt2; COMMIT ; END