MySQL 水平分区

分区概念

分区是把表分成几个小部分,即对表的行进行划分。

分区的优点
  • 可以提高数据库的性能;
  • 对大表(行较多)的维护更快、更容易,因为数据分布在不同的逻辑文件上;
  • 删除分区或它的数据是容易的,因为它不影响其他表。
分区类型

分区具有如下4种类型:

  • Range分区:是对一个连续性的行值,按范围进行分区;比如:id小于100;id大于100小于200;日期在201906到201907之间;
  • List分区:跟range分区类似,不过它存放的是一个离散值的集合。
  • Hash分区:对用户定义的表达式所返回的值来进行分区。可以写partitions (分区数目),或直接使用分区语句,比如partition p0 values in……。
  • Key分区:与hash分区类似,只不过分区支持一列或多列,并且MySQL服务器自身提供hash函数。
具体描述:

分区语法:

按range分区

CREATE TABLE `log` (
  `server` int(11) NOT NULL,
  `log_ym` int(11) NOT NULL,
  `date_time` datetime NOT NULL,
  `online` int(11) DEFAULT NULL,
  `register` int(11) DEFAULT NULL,
  `pay` decimal(15,2) DEFAULT NULL,
  PRIMARY KEY (`server`,`date_time`,`log_ym`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
/*!50100 PARTITION BY RANGE (log_ym)
(PARTITION p201903 VALUES LESS THAN (201904) ENGINE = InnoDB,
 PARTITION p201904 VALUES LESS THAN (201905) ENGINE = InnoDB,
 PARTITION p201905 VALUES LESS THAN (201906) ENGINE = InnoDB,
 PARTITION p201906 VALUES LESS THAN (201907) ENGINE = InnoDB,
 PARTITION p201907 VALUES LESS THAN (201908) ENGINE = InnoDB,
 PARTITION p201908 VALUES LESS THAN (201909) ENGINE = InnoDB,
 PARTITION p201909 VALUES LESS THAN (201910) ENGINE = InnoDB,
 PARTITION p201910 VALUES LESS THAN (201911) ENGINE = InnoDB,
 PARTITION p201911 VALUES LESS THAN (201912) ENGINE = InnoDB,
 PARTITION p201912 VALUES LESS THAN (202001) ENGINE = InnoDB,
 PARTITION another VALUES LESS THAN MAXVALUE ENGINE = InnoDB) */;

按list分区

create table orders_list
(
id int auto_increment,
customer_surname varchar(30),
store_id int,
salesperson_id int,
order_Date date,
note varchar(500),
index idx(id)
) engine=myisam  partition by list(store_id)
(
partition p0 values in(1,3),
partition p1 values in(2,4,6),
partition p3 values in(10)
);

按key分区


create table orders_key
(
id int auto_increment,
customer_surname varchar(30),
store_id int,
alesperson_id int,
order_Date date,
note varcahr(500),
index_idx(id)
) engine=myisam  partition by key(order_date) partitions 4;

按hash分区

create table orders_hash
(
id int auto_increment primary key,
cutomer_surname varchar(30),
store_id int,
salesperon_id int,
order_date date,
note varcahr(500)
) engine=myisam  partition by hash(id) partitions 4;

如果分为4个分区,那当我插入数据时,哪些数据是放在哪些分区里呢? 
当我对某个id值进行检索时,它明确说放到哪个分区里?或者说是有什么内部机制?
使用hash分区,最主要就是确保数据的分配,它是基于create table时提供的表达式。
不必定义单独的分区,只要使用partitions关键字和所需要分多少个区的数字。语句如上所述。
1.测试添加分区和删除分区
###添加删除range分区
(1)创建一个分区:
CREATE TABLE titles (
    emp_no      INT NOT NULL,
    title       VARCHAR(50)     NOT NULL,
    from_date   DATE            NOT NULL,
    to_date     DATE,
    KEY         (emp_no),
    PRIMARY KEY (emp_no,title, from_date)
) partition by range columns(from_date)
(partition p01 values less than ('1985-12-31'),
partition p02 values less than ('1990-12-31'),
partition p03 values less than ('1995-12-31'),
partition p04 values less than ('2000-12-31'),
partition p05 values less than ('2005-12-31'),
partition p06 values less than ('2010-12-31'),
partition p07 values less than ('2015-12-31'),
partition p08 values less than ('2020-12-31'),
partition p09 values less than ('2025-12-31'),
partition p10 values less than ('2030-12-31')
);
导入数据
mysql> source titles.sql
 
(2)添加分区:
备注:不能超过p04的范围,严格递增每个分区,即最小不能小于前一个分区
下面新曾了两个分区n01和n02
 alter table titles
 reorganize partition p04 into(
 partition n01 values less than('1997-12-31'),
 partition n02 values less than('1998-12-31'),
 partition p04 values less than('2000-12-31')
 );
 
(3)删除分区:
删除分区即删除数据。
mysql> select count(*) from titles where from_date<'1985-12-31';
+----------+
| count(*) |
+----------+
|    18238 |
+----------+
1 row in set (0.09 sec)
 
mysql> alter table titles drop partition p01;
Query OK, 0 rows affected (0.05 sec)
Records: 0  Duplicates: 0  Warnings: 0
 
mysql> select count(*) from titles where from_date<'1985-12-31';
+----------+
| count(*) |
+----------+
|        0 |
+----------+
1 row in set (0.04 sec)
 
###添加删除list分区
(1)创建list分区
CREATE TABLE titles (
    emp_no      INT NOT NULL,
    title       VARCHAR(50)     NOT NULL,
    from_date   DATE            NOT NULL,
    to_date     DATE,
    KEY         (emp_no),
    PRIMARY KEY (emp_no,title, from_date)
) partition by list columns(title)
(
partition p0 values in ('Assistant Engineer'),
partition p1 values in ('Engineer'),
partition p2 values in ('Manager'),
partition p3 values in ('Senior Engineer'),
partition p4 values in ('Senior Staff'),
partition p5 values in ('Staff'),
partition p6 values in ('Technique Leader')
);
导入数据
titles.sql 是employees数据库导出的数据
mysql> source titles.sql
 
(2)添加分区
mysql> alter table titles add partition(partition p7 values in('CEO'));
Query OK, 0 rows affected (0.07 sec)
Records: 0  Duplicates: 0  Warnings: 0
 
(3)删除分区:
mysql> alter table titles drop partition p0;
Query OK, 0 rows affected (0.04 sec)
Records: 0  Duplicates: 0  Warnings: 0
 
###添加删除hash分区
(1)创建hash分区
CREATE TABLE titles (
    emp_no      INT NOT NULL,
    title       VARCHAR(50)     NOT NULL,
    from_date   DATE            NOT NULL,
    to_date     DATE,
    KEY         (emp_no),
    PRIMARY KEY (emp_no,title, from_date)
) partition by hash(emp_no)
partitions 4;
导入数据:
mysql> source titles.sql
 
(2)删除hash分区
4个分区减少到两个,4-2=2
mysql> alter table titles coalesce partition 2;
Query OK, 443308 rows affected (12.41 sec)
Records: 443308  Duplicates: 0  Warnings: 0
 
(3)添加hash分区
增加到5个,2+3=5
mysql> alter table titles add partition partitions 3;
Query OK, 443308 rows affected (11.54 sec)
Records: 443308  Duplicates: 0  Warnings: 0
 
###添加删除key分区
(1)创建key分区
CREATE TABLE titles (
    emp_no      INT NOT NULL,
    title       VARCHAR(50)     NOT NULL,
    from_date   DATE            NOT NULL,
    to_date     DATE,
    KEY         (emp_no),
    PRIMARY KEY (emp_no,title, from_date)
) partition by key(emp_no)
partitions 4;
导入数据
mysql> source titles.sql
 
(2)删除分区,同hash
mysql> alter table titles coalesce partition 2;
Query OK, 443308 rows affected (7.86 sec)
Records: 443308  Duplicates: 0  Warnings: 0
 
(3)添加分区,同hash
mysql> alter table titles add partition partitions 3;
Query OK, 443308 rows affected (6.17 sec)
Records: 443308  Duplicates: 0  Warnings: 0
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
MySQL分区是一种将大型表水平分成多个部分的技术,这有助于提高查询和数据管理的效率。在 MySQL 中,可以使用 RANGE、LIST、HASH 和 KEY 四种分区类型来定义分区方式。 下面是 MySQL分区的详细操作步骤: 1. 创建表时定义分区方式 在创建表的时候,可以指定表的分区方式。例如,使用 RANGE 分区方式将表按照数值范围进行分区: ``` CREATE TABLE mytable ( id INT, value INT ) PARTITION BY RANGE (value) ( PARTITION p0 VALUES LESS THAN (10), PARTITION p1 VALUES LESS THAN (20), PARTITION p2 VALUES LESS THAN (MAXVALUE) ); ``` 2. 插入数据 向表中插入数据时,MySQL 会自动将数据插入到正确的分区中。例如,插入一个 value 值为 5 的数据: ``` INSERT INTO mytable (id, value) VALUES (1, 5); ``` 3. 查询数据 在查询数据时,MySQL 可以仅查询特定的分区,而不必扫描整个表。例如,查询 value 值在 10 到 20 之间的数据: ``` SELECT * FROM mytable PARTITION (p1); ``` 4. 修改分区 可以使用 ALTER TABLE 语句修改表的分区方式,例如,将表从 RANGE 分区方式修改为 HASH 分区方式: ``` ALTER TABLE mytable PARTITION BY HASH(value) PARTITIONS 4; ``` 5. 合并分区 可以使用 ALTER TABLE 语句将相邻的分区合并为一个分区,例如,将分区 p1 和 p2 合并为一个分区: ``` ALTER TABLE mytable COALESCE PARTITION p1, p2 INTO p3; ``` 6. 删除分区 可以使用 ALTER TABLE 语句删除表的某个分区,例如,删除分区 p0: ``` ALTER TABLE mytable DROP PARTITION p0; ``` 以上就是 MySQL分区的详细操作步骤,可以根据实际需求选择不同的分区方式来提高查询和数据管理的效率。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值