数据表分区方法与使用

参考官网手册

检查是否支持分区:

show plugins;

如果显示有
partition ACTIVE,则表示是支持分区

分区类型:
范围(range):通过指定的列中的值作为区间范围
列表(list):与range相似,区别是匹配一个指定的列值
哈希(hash):是基于用户定义的函数对列的值计算后返回结果决定保存在哪一个分区中
键值(key):与hash类似,基于一个或多个列来评估,并且由mysql服务器提供函数

基于 range,其中的rang中结果值为 整型
as:

CREATE TABLE members (
firstname VARCHAR(25) NOT NULL,
lastname VARCHAR(25) NOT NULL,
username VARCHAR(16) NOT NULL,
email VARCHAR(35),
joined DATE NOT NULL
)
PARTITION BY RANGE( YEAR(joined) ) (
PARTITION p0 VALUES LESS THAN (1960),
PARTITION p1 VALUES LESS THAN (1970),
PARTITION p2 VALUES LESS THAN (1980),
PARTITION p3 VALUES LESS THAN (1990),
PARTITION p4 VALUES LESS THAN MAXVALUE
);
#或者:
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 MAXVALUE
);

基于 list:(list列表结果为整型)
与range类似,主要区别在于,list(表达式)中的表达式值为指定的一组具体值(即枚举值),
并且list中的值一定要在分区中,并且分区中的结果为整型:
as:

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,
store_id INT
)
PARTITION BY LIST(store_id) (
PARTITION pNorth VALUES IN (3,5,6,9,17),
PARTITION pEast VALUES IN (1,2,10,11,19,20),
PARTITION pWest VALUES IN (4,12,13,14,18),
PARTITION pCentral VALUES IN (7,8,15,16)
);

基于 range columns:(列的类型可为 string,date,datetime)
与range类似,但范围列不接受表达式,只接收列名称
范围列是基于比较元组(列表值)而不是标量之间比较
格式如下:

CREATE TABLE table_name
PARTITIONED BY RANGE COLUMNS(column_list) (
PARTITION partition_name VALUES LESS THAN (value_list)[,
PARTITION partition_name VALUES LESS THAN (value_list)][,
...]
)
column_list:
column_name[, column_name][, ...]
value_list:
value[, value][, ...]
--------------------
as:
create table rcx(
a int,
b int,
c char(3),
d int
)
partition by range columns(a,b,c)(
partition p0 values less than (4,2,10),
partition p1 values less than (10,20,‘mmm‘),
partition p2 values less than (maxvalue,maxvalue,maxvalue)
)

#as:
CREATE TABLE employees_by_lname (
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 COLUMNS (lname) (
PARTITION p0 VALUES LESS THAN (‘g‘),
PARTITION p1 VALUES LESS THAN (‘m‘),
PARTITION p2 VALUES LESS THAN (‘t‘),
PARTITION p3 VALUES LESS THAN (MAXVALUE)
);

基于list columns:(表达式中值的类型为:string,date,datetime)
as:

CREATE TABLE customers_1 (
first_name VARCHAR(25),
last_name VARCHAR(25),
street_1 VARCHAR(30),
street_2 VARCHAR(30),
city VARCHAR(15),
renewal DATE
)
PARTITION BY LIST COLUMNS(city) (
PARTITION pRegion_1 VALUES IN(‘Oskarshamn‘, ‘Högsby‘, ‘Mönsterås‘),
PARTITION pRegion_2 VALUES IN(‘Vimmerby‘, ‘Hultsfred‘, ‘Västervik‘),
PARTITION pRegion_3 VALUES IN(‘Nässjö‘, ‘Eksjö‘, ‘Vetlanda‘),
PARTITION pRegion_4 VALUES IN(‘Uppvidinge‘, ‘Alvesta‘, ‘Växjo‘)
);
##############
CREATE TABLE customers_2 (
first_name VARCHAR(25),
last_name VARCHAR(25),
street_1 VARCHAR(30),
street_2 VARCHAR(30),
city VARCHAR(15),
renewal DATE
)
PARTITION BY LIST COLUMNS(renewal) (
PARTITION pWeek_1 VALUES IN(‘2010-02-01‘, ‘2010-02-02‘, ‘2010-02-03‘,
‘2010-02-04‘, ‘2010-02-05‘, ‘2010-02-06‘, ‘2010-02-07‘),
PARTITION pWeek_2 VALUES IN(‘2010-02-08‘, ‘2010-02-09‘, ‘2010-02-10‘,
‘2010-02-11‘, ‘2010-02-12‘, ‘2010-02-13‘, ‘2010-02-14‘),
PARTITION pWeek_3 VALUES IN(‘2010-02-15‘, ‘2010-02-16‘, ‘2010-02-17‘,
‘2010-02-18‘, ‘2010-02-19‘, ‘2010-02-20‘, ‘2010-02-21‘),
PARTITION pWeek_4 VALUES IN(‘2010-02-22‘, ‘2010-02-23‘, ‘2010-02-24‘,
‘2010-02-25‘, ‘2010-02-26‘, ‘2010-02-27‘, ‘2010-02-28‘)
);

以上可以用 range columns代替:

CREATE TABLE customers_3 (
first_name VARCHAR(25),
last_name VARCHAR(25),
street_1 VARCHAR(30),
street_2 VARCHAR(30),
city VARCHAR(15),
renewal DATE
)
PARTITION BY RANGE COLUMNS(renewal) (
PARTITION pWeek_1 VALUES LESS THAN(‘2010-02-09‘),
PARTITION pWeek_2 VALUES LESS THAN(‘2010-02-15‘),
PARTITION pWeek_3 VALUES LESS THAN(‘2010-02-22‘),
PARTITION pWeek_4 VALUES LESS THAN(‘2010-03-01‘)
);

hash分区:
主要用于保证预定数量分区间数据分布均匀,hash返回的类型为整数,
用取模方法分区,即 (hash结果mod)/分区数)
as:

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,
store_id INT
)
PARTITION BY HASH(store_id)
PARTITIONS 4;

此时,store_id会被4整除,此时相当于分区为 0,1,2,3,即余数,
默认时用1开始,即分区 1,2,3,4,当值为0时,在1区,值为1时,在2区,...

as:

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,
store_id INT
)
PARTITION BY HASH( YEAR(hired) )
PARTITIONS 4;

线性hash(linear hash):
与 普通hash类似,不同之处是用了 linera hash,还有就是分区算法用的是(线性的2的幂的运算法则)

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,
store_id INT
)
PARTITION BY LINEAR HASH( YEAR(hired) )
PARTITIONS 4; 

key分区:
与hash类似,但是不允许用用户自定义的表达式,可以不用手动指定分区键,
默认会选择使用主键/唯一键作为分区键,没有主键/唯一键,则要指定分区键,
key的使用类似 hash
as:

CREATE TABLE k1 (
id INT NOT NULL PRIMARY KEY,
name VARCHAR(20)
)
PARTITION BY KEY()
PARTITIONS 2;

##as:
CREATE TABLE tm1 (
s1 CHAR(32) PRIMARY KEY
)
PARTITION BY KEY(s1)
PARTITIONS 10;

其实如 hash一样,可以使用 linear key,
as:

CREATE TABLE tk (
col1 INT NOT NULL,
col2 CHAR(5),
col3 DATE
)
PARTITION BY LINEAR KEY (col1)
PARTITIONS 3;

子分区:是在每一个分区进一步划分。

CREATE TABLE ts (id INT, purchased DATE)
PARTITION BY RANGE( YEAR(purchased) )
SUBPARTITION BY HASH( TO_DAYS(purchased) )
SUBPARTITIONS 2 (
PARTITION p0 VALUES LESS THAN (1990),
PARTITION p1 VALUES LESS THAN (2000),
PARTITION p2 VALUES LESS THAN MAXVALUE
);

以上实现就有6个分区了  

以下为分区的管理,即所谓的增删改查:

清除表中所有的分区: 

alter table 表名 remove PARTITIONING;

range/list类型分区(REORGANIZE PARTITION 只用于 range/list类型的分区):
增加分区:
当建立表时,还没有记录,则
as:

#range分区类型
CREATE TABLE tr (id INT, name VARCHAR(50), purchased DATE)
         PARTITION BY RANGE( YEAR(purchased) ) (
             PARTITION p0 VALUES LESS THAN (1990),
             PARTITION p1 VALUES LESS THAN (1995),
             PARTITION p2 VALUES LESS THAN (2000),
             PARTITION p3 VALUES LESS THAN (2005)
         );

#list分区类型:
CREATE TABLE tt (
    id INT,
    data INT
)
PARTITION BY LIST(data) (
    PARTITION p0 VALUES IN (5, 10, 15),
    PARTITION p1 VALUES IN (6, 12, 18)
);

当增加分区时,已经存在记录或已定义好表结构,则:
当之前没有分区时:

ALTER TABLE 表名
    PARTITION BY 分区方法
    (定义)

as:

CREATE TABLE members (
    id INT,
    fname VARCHAR(25),
    lname VARCHAR(25),
    dob DATE
)
#增加分区(之前没有分区),则:
alter table members
PARTITION by range(year(dob))(
             PARTITION p0 VALUES LESS THAN (1990),
             PARTITION p1 VALUES LESS THAN (1995),
             PARTITION p2 VALUES LESS THAN (2000),
             PARTITION p3 VALUES LESS THAN (2005)
)

#已经存在分区时:
alter table 表名 add partition (分区定义):
#range 类型:
#as:
CREATE TABLE members (
    id INT,
    fname VARCHAR(25),
    lname VARCHAR(25),
    dob DATE
)
PARTITION BY RANGE( YEAR(dob) ) (
    PARTITION p0 VALUES LESS THAN (1970),
    PARTITION p1 VALUES LESS THAN (1980),
    PARTITION p2 VALUES LESS THAN (1990)
);

#如果有分区,则:
ALTER TABLE members ADD PARTITION (PARTITION p3 VALUES LESS THAN (2000));

#list类型:
#没有分区时:
alter table members PARTITION by list(year(dob))(
    PARTITION p0 VALUES IN (5, 10, 15),
    PARTITION p1 VALUES IN (6, 12, 18)
)

#有分区时,则:
ALTER TABLE tt ADD PARTITION (PARTITION p2 VALUES IN (7, 14, 21));

#当用explain检索是否使用索引或分区时,可用
#explain PARTITIONS sql语句;

#删除分区,同时删除记录
alert table 表名 drop partition 分区名;
as:
ALTER TABLE tr DROP PARTITION p2;

#把一个分区分割成多个分区
alter table 表名
	reorganize partition 分区名 into(
		分区定义语句,
		分区定义语句,
		....
	)
#range类型:
#as:
ALTER TABLE members
    REORGANIZE PARTITION p0 INTO (
        PARTITION n0 VALUES LESS THAN (1960),
        PARTITION n1 VALUES LESS THAN (1970)
);

#合并分区,把多个分区合并成一个分区或多个分区:(数据不会丢失)
alter table 表名 REORGANIZE PARTITION 分区名1,分区名2,... into(
	分区定义语句,
	分区定义语句,
	...
)
#range类型:
ALTER TABLE members REORGANIZE PARTITION s0,s1 INTO (
    PARTITION p0 VALUES LESS THAN (1970)
);
#或如:
ALTER TABLE members REORGANIZE PARTITION p0,p1,p2,p3 INTO (
    PARTITION m0 VALUES LESS THAN (1980),
    PARTITION m1 VALUES LESS THAN (2000)
);

#list 类型:
ALTER TABLE tt ADD PARTITION (PARTITION np VALUES IN (4, 8));
ALTER TABLE tt REORGANIZE PARTITION p1,np INTO (
    PARTITION p1 VALUES IN (6, 18),
    PARTITION np VALUES in (4, 8, 12)
);

#hash/key分区类型
#创建分区,如用 hash 创建为12个分区:
CREATE TABLE clients (
    id INT,
    fname VARCHAR(30),
    lname VARCHAR(30),
    signed DATE
)
PARTITION BY HASH( MONTH(signed) )
PARTITIONS 12;

#当给没有创建过分区的表进行分区时(hash):
ALTER TABLE members
    PARTITION BY HASH( YEAR(dob) )
    PARTITIONS 8;

#当从12个修改为8个分区时(即相当于移除4个):
ALTER TABLE clients COALESCE PARTITION 4;

#当把 12个分区重新分成18个时(相当于增6个分区):
ALTER TABLE clients ADD PARTITION PARTITIONS 6;

  

  

  

  

  

 

  

  

  

  

  

  

  

时间: 2024-10-13 01:45:32

数据表分区方法与使用的相关文章

Oracle 数据表之分区表

一.分区方法 建分区表准备: 1,创建4个测试用的表空间,每个表空间作为一个独立分区(考虑到Oracle中分区映射的实现方式,建议将表中的分区数设置为2的乘方,以便使数据均匀分布) create tablespace partition1 datafile '/home/oracle/app/oradata/orcl/partition1.dbf' size 20m; create tablespace partition2 datafile '/home/oracle/app/oradata/

MySQL(九)之数据表的查询详解(SELECT语法)二

上一篇讲了比较简单的单表查询以及MySQL的组函数,这一篇给大家分享一点比较难得知识了,关于多表查询,子查询,左连接,外连接等等.希望大家能都得到帮助! 在开始之前因为要多表查询,所以搭建好环境: 1)创建数据表suppliers 前面已经有一张表是book表,我们在建立一张suppliers(供应商)表和前面的book表对应. 也就是说 让book中s_id字段值指向suppliers的主键值,创建一个外键约束关系. 其实这里并没有达到真正的外键约束关系,只是模拟,让fruits中的s_id中

SQL基础:数据表的创建

1. 先选择创建表所在的数据库 2. 创建表 3. 查看表是否创建成功 4. 主键:要求主键列的数据唯一,且不允许为空.主键能够唯一的标识表中的每一条记录,可以结合外键来定义不同数据表之间的关系,并且可以加快数据库查询的速度. 主键分为:单字段主键和多字段联合主键. 4.1 单字段主键 4.1.1 定义方式一:在定义列的同时指定主键 4.1.2 定义方式二:在定义完所有的列之后指定主键 4.2 多字段联合主键 5. 使用外键约束 外键用来在两个表之间建立连接,可以是一列或多列.一个表的外键可以是

数据库设计之数据库,数据表和字段等的命名总结

数据库命名规则: 根据项目的实际意思来命名. 数据表命名规则: 1.数据表的命名大部分都是以名词的复数形式并且都为小写: 2.尽量使用前缀"table_": 3.如果数据表的表名是由多个单词组成,则尽量用下划线连接起来:但是不要超过30个字符,一旦超过30个字符,则使用缩写来缩短表名的长度: 字段命名规则: 1.首先命名字段尽量采用小写,并且是采用有意义的单词: 2.使用前缀,前缀尽量用表的"前四个字母+下划线组成": 3.如果字段名由多个单词组成,则使用下划线来进

php 实现 mysql数据表优化与修复

<?php $link = mysql_connect("localhost", "root", "") or die("errro:" . mysql_error()); mysql_query("set names utf8"); mysql_select_db("数据库名", $link); /* // 展示数据表相关信息 $sql = "show table st

oracle的学习 第二节:创建数据表

学习内容: A.创建数据库和表空间 B.创建用户和分配权限 C.创建数据表 一.创建数据库和表空间 (一)SQL语言的基本概念 1.概念 高级的结构化查询语言:沟通数据库服务器和客户的重要桥梁. PL/sql语言是结构化的查询语言. 2.分类: 数据定义语言  :create  alter  drop 数据操作语言: insert update delete 数据控制语言:select (二)创建数据库的两种方式 方式一:图形界面: 方式二:create  Datebase命令方法.(常用) 具

SQL Server 数据表复制

一.复制 A 的内容到新表 说明: 有数据表 A, 希望将他的内容导出到另一张表 B,此时 B 并未创建,希望在导出的同时创建表 B. SELECT * INTO B [IN externaldatabase]  FROM A 二.复制 A 的内容到已有表 B 说明: 有数据表 A, 希望将他的内容导出到另一张表 B,此时 B 已创建,希望在导出的同时创建表 B. insert into B (B_column_1, B_column_2, ...) select A_column_1, A_c

数据库系列学习(二)-数据表的创建和管理

1.数据类型 A:整数类型 bit,int,smallint,tinyint [与操作系统位数有关] B:数值类型 decimal,numeric,money,smallmoney,float,real [可存小数] C:字符相关类型 char,varchar,text,nchar,nvarchar,ntext D:日期时间类型 datetime(精确到0.01秒),smalldatetime(精确到分钟),timestamp E:二进制类型 image [经图片,视频转为二进制,保存到数据库]

【SQL 代码】SQL复制数据表及表结构

select * into 目标表名 from 源表名 insert into 目标表名(fld1, fld2) select fld1, 5 from 源表名 以上两句都是将'源表'的数据插入到'目标表',但两句又有区别的: 第一句(select into from)要求目标表不存在,因为在插入时会自动创建. 第二句(insert into select from)要求目标表存在,由于目标表已经存在,所以我们除了插入源表的字段外,还可以插入常量,如例中的:5. 示例 目前有数据如下: 现在要将