分區是根據必定的規則,數據庫把一個表分解成多個更小的、更容易管理的部分。就訪問數據庫應用而言,邏輯上就只有一個表或者一個索引,但實際上這個表可能有N個物理分區對象組成,每一個分區都是一個獨立的對象,能夠獨立處理,能夠做爲表的一部分進行處理。分區對應用來講是徹底透明的,不影響應用的業務邏輯。分區有利於管理很是大的表,它採用分而治之的邏輯,分區引入了分區鍵的概念,分區鍵用於根據某個區間值(或者範圍值)、特定值列表或者hash函數值執行數據的彙集,讓數據根據規則分佈在不一樣的分區中,讓一個大對象分割爲一些小對象。mysql
range 分區:基於一個給定的連續區間範圍(區間要求連續而且不能重疊),把數據分配到不一樣的分區
list 分區:相似於range分區,區別在於list分區是居於枚舉出的值列表分區,range是基於給定的連續區間範圍分區
hash 分區:基於給定的分區個數,把數據分配到不一樣的分區
key 分區:相似於hash分區sql
注意:不管哪一種分區,要麼你分區表上沒有主鍵/惟一鍵,要麼分區表的主鍵/惟一鍵都必須包含分區鍵,也就是說不能使用主鍵/惟一鍵字段以外的其它字段分區。
若是你想在分區表使用時間字段來做爲分區鍵,你應該把ID和時間字段設爲分區表的組合主鍵。數據庫
1.和單個磁盤或者文件系統分區相比,能夠存儲更多數據
2.優化查詢。在where子句中包含分區條件時,能夠只掃描必要的一個或者多個分區來提升查詢效率;同時在涉及sum()和count()這類聚合函數的查詢時,能夠容易的在每一個分區上並行處理,最終只須要彙總全部分區獲得的結果
3.對於已通過期或者不須要保存的數據,能夠經過刪除與這些數據有關的分區來快速刪除數據
4.跨多個磁盤來分散數據查詢,以得到更大的查詢吞吐量less
經過show variables like ‘%datadir%’;命令查看mysql的data存放目錄,進入所在的數據庫目錄。不一樣的引擎數據庫文件格式不一樣。函數
mysql> show variables like '%datadir%'; +---------------+---------------------------------------------+ | Variable_name | Value | +---------------+---------------------------------------------+ | datadir | C:\ProgramData\MySQL\MySQL Server 5.7\Data\ | +---------------+---------------------------------------------+
innodb: 只有設置成獨立表空間才能作成功表分區
.frm : 表結構
.ibd : 數據 + 索引優化
MySQL有五種分區類型 range、list、hash、key、子分區,其中最經常使用的是range和list分區spa
首先須要肯定你使用的數據庫有沒有開啓分區功能插件
-- 查看mysql版本
select version( ) , mysql5.1開始支持數據表分區code
-- 查看分區插件是否激活 partition active
show plugins; 對象
(1) range分區
給定一個連續區間的範圍值進行分區,某個字段的值知足這個範圍就會被分配到該分區。適用於字段的值是連續的區間的字段,如 日期範圍, 連續的數字。
-- 語法
create table <table> ( // 字段 ) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 partition by range (分區字段) ( partition <分區名稱> values less than (Value), partition <分區名稱> values less than (Value), ... partition <分區名稱> values less than maxvalue );
-- 字段介紹
range:表示按範圍分區
分區字段:表示要按照哪一個字段進行分區,能夠是一個字段名,也能夠是對某個字段進行表達式運算如year(create_time),使用range最終的值必須是數字
分區名稱: 要保證不一樣,也能夠採用 p0、p一、p2 這樣的分區名稱,
less than : 表示小於
Value : 表示要小於某個具體的值,如 less than (10) 那麼分區字段的值小於10的都會被分到這個分區
maxvalue: 表示一個最大的值
注意:range 對應的分區鍵值必須是數字值,可使用range columns(分區字段) 對非int型作分區,如字符串,對於日期類型的可使用year()、to_days()、to_seconds()等函數。
-- 建立方式
分區能夠在建立表的時候進行分區,也能夠在建立表以後進行分區
alter table <table> partition by RANGE(id) ( PARTITION p0 VALUES LESS THAN (1000000), PARTITION p1 VALUES LESS THAN (2000000), PARTITION p2 VALUES LESS THAN (3000000), PARTITION p3 VALUES LESS THAN (4000000), PARTITION p4 VALUES LESS THAN MAXVALUE ); CREATE TABLE `tbl_user_part` ( `id` int(11) NOT NULL , `username` varchar(255) DEFAULT NULL, `email` varchar(20) DEFAULT NULL, `age` tinyint(4) DEFAULT NULL, `type` int(11) DEFAULT NULL, `create_time` datetime DEFAULT CURRENT_TIMESTAMP -- PRIMARY KEY (`id`,`age`) ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 PARTITION BY RANGE (age) ( PARTITION p0 VALUES LESS THAN (20), PARTITION p1 VALUES LESS THAN (40), PARTITION p2 VALUES LESS THAN (60), PARTITION p3 VALUES LESS THAN (80), PARTITION p4 VALUES LESS THAN MAXVALUE );
-- 常見錯誤
在建立分區的時候常常會遇到這個錯誤:A PRIMARY KEY must include all columns in the table’s partitioning function。意思是說分區的字段必須是要包含在主鍵當中。
可使用PRIMARY KEY (id,xxx)來將多個字段做爲主鍵。在作分區表時,選擇分區的依據字段時要謹慎,須要仔細斟酌這個字段拿來作爲分區依據是否合適,這個字段加入到主鍵中作爲複合主鍵是否適合。
(2) list 分區-- 語法
create table <table> ( // 字段 ) ENGINE=數據庫引擎 DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 partition by LIST (分區字段或者基於該字段的返回的整數值的表達式) ( partition <分區名稱> values IN (Value1,Value2, Value3), ... partition <分區名稱> values IN (Value4, Value5), );
(3) 關於 hash 和 key 分區這裏不作介紹.........
mysql提供了添加、刪除、重定義、合併、拆分分區的命令,這些操做均可以經過alter table 命令來實現
-- 刪除list或者range分區(同時刪除分區對應的數據) alter table <table> drop partition <分區名稱>; 注意: 刪除分區的同時會刪除數據 -- 取消分區,不刪除數據 alter table <table> remove partitioning; -- range添加新分區 alter table <table> add partition(partition p4 values less than MAXVALUE); 注意:RANGE 的分區方式在加分區的時候,只能從最大值後面加,而最大值前面不能夠添加 -- list添加新分區 alter table <table> add partition(partition p4 values in (25,26,28));