MySQL支持的分區類型爲水平分區,並不支持垂直分區。
水平分區,以行爲單位,劃分到不同的物理文件中;垂直分區即針對列劃分。
MySQL的分區,除了InnoDB支持,MyISAM也支持,所以分區並不是引擎級別的事兒。
分區並不一定會讓訪問變得更快,尤其是OLTP應用,OLAP應用使用分區的效果往往更好。
MySQL支持的如下幾種分區類型。
- RANGE 行數據基於一個給定連續區間的列值劃分。
- LIST 和RANGE類似,只是LIST面向的不是連續區間值,而是離散的集合。
- HASH 根據自定義的表達式返回值進行分區,不支持負數返回。
- KEY 根據MySQL提供的hash函數進行分區
不論按照哪種類型進行分區,如果當前表有主鍵或者唯一索引,分區列必須是唯一索引的組成部分。反過來,如果當前表沒有定義主鍵也沒有唯一索引,分區列可以是任何列。
分區操作示例:
create table sales(id int, price decimal(9,2), season int, finyear datetime)
partition by range(season) (
prtition s1 values less than (4),
partition s2 values less than (7),
partition s3 values less than (10),
partition s4 values less than (13));
使用函數獲取range值
create table sales(id int, price decimal(9,2), season int, finyear datetime)
partition by range(year(finyear)) (
partition s1 values less than (2016),
partition s2 values less than (2017),
partition s3 values less than (2018),
partition s4 values less than (2020));
create table sales(id int, price decimal(9,2), season int, finyear datetime)
partition by range(year(finyear)*100+ month(finyear)) (
partition s1 values less than (201804),
partition s2 values less than (201807),
partition s3 values less than (201810),
partition s4 values less than (201813));
LIST分區示例
create table sales(id int, price decimal(9,2), season int, finyear datetime)
partition by LIST(id) (
partition s1 values in (1,3,5,7,9),
partition s2 values in (2,4,6,8,10));
HASH分區示例
create table sales(id int, price decimal(9,2), season int, finyear datetime) engine=innodb
partition by hash(year(finyear));
KEY分區示例
create table sales(id int, price decimal(9,2), season int, finyear datetime) engine=innodb
partition by key(finyear);
分區後的數據存儲結構及使用效果
以RANGE分區爲例
插入數據
insert into sales select 1,10.05,1,'2018-01-01';
insert into sales select 2,10.05,3,'2018-03-01';
insert into sales select 3,10.05,4,'2018-04-01';
執行查詢
explain partitions
select * from sales where finyear < '2016-01-01';
可以看到,查詢優化器,直接跳過第四個分區,在前三個分區中查詢,這就是要的效果。
除了分區,還有分表、分庫、分片操作,每一個都很重要,也都有各自的適用場景。