热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

MySQL的分区(一)

mysql支持范围分区(range)、列表分区(list)、column分区、哈希分区(hash)、key分区、字段列表分区等以timestamp类型字段作为分区键进

mysql支持范围分区(range)、列表分区(list)、column分区、哈希分区(hash)、key分区、字段列表分区等

以timestamp类型字段作为分区键进行范围分区,有两种方式:

CREATE TABLE quarterly_report_status (

report_id INT NOT NULL,

report_status VARCHAR(20) NOT NULL,

report_updated TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP

)

PARTITION BY RANGE ( UNIX_TIMESTAMP(report_updated) ) (

PARTITION p0 VALUES LESS THAN ( UNIX_TIMESTAMP('2008-01-01 00:00:00') ),

PARTITION p1 VALUES LESS THAN ( UNIX_TIMESTAMP('2008-04-01 00:00:00') ),

PARTITION p2 VALUES LESS THAN ( UNIX_TIMESTAMP('2008-07-01 00:00:00') ),

PARTITION p3 VALUES LESS THAN ( UNIX_TIMESTAMP('2008-10-01 00:00:00') ),

PARTITION p4 VALUES LESS THAN ( UNIX_TIMESTAMP('2009-01-01 00:00:00') ),

PARTITION p5 VALUES LESS THAN ( UNIX_TIMESTAMP('2009-04-01 00:00:00') ),

PARTITION p6 VALUES LESS THAN ( UNIX_TIMESTAMP('2009-07-01 00:00:00') ),

PARTITION p7 VALUES LESS THAN ( UNIX_TIMESTAMP('2009-10-01 00:00:00') ),

PARTITION p8 VALUES LESS THAN ( UNIX_TIMESTAMP('2010-01-01 00:00:00') ),

PARTITION p9 VALUES LESS THAN (MAXVALUE)

);

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

);

在mysql5.7中timestamp范围分区表只能使用上面两种格式,使用to_days可能触发bug。

date类型的分区:

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 COLUMNS(joined) (

    PARTITION p0 VALUES LESS THAN ('1960-01-01'),

    PARTITION p1 VALUES LESS THAN ('1970-01-01'),

    PARTITION p2 VALUES LESS THAN ('1980-01-01'),

    PARTITION p3 VALUES LESS THAN ('1990-01-01'),

    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,

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)

);

使用ignore关键字,可以在插入多条数据时忽略没有匹配分区的数据,不报错:

mysql> CREATE TABLE h3 (

-> c1 INT,

-> c2 INT

-> )

-> PARTITION BY LIST(c1) (

-> PARTITION p0 VALUES IN (1, 4, 7),

-> PARTITION p1 VALUES IN (2, 5, 8)

-> );

Query OK, 0 rows affected (0.11 sec)

mysql> INSERT INTO h3 VALUES (3, 5);

ERROR 1525 (HY000): Table has no partition for value 3

mysql> INSERT IGNORE INTO h3 VALUES (2, 5), (6, 10), (7, 5), (3, 1), (1, 9);

Query OK, 3 rows affected (0.00 sec)

Records: 5 Duplicates: 2 Warnings: 0

mysql> SELECT * FROM h3;

+------+------+

| c1 | c2 |

+------+------+

| 7 | 5 |

| 1 | 9 |

| 2 | 5 |

+------+------+

3 rows in set (0.00 sec)

可以在定义表时指定分区属性,也可以使用alter table进行修改:

ALTER TABLE employees 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)

);

range columns不支持表达式,仅支持一或多个列名。

由于字符集character sets和collations的排列顺序不同,当进行数据迁移或者修改库、表、列的字符集时,

有可能因此而出现报错。比如对于大小写不敏感的collation,and排列顺序在Andersen之前,

但对于大小写敏感的collation就不是。

使用多个字段分区时,是按照字段顺序进行比较的,以下语句正确:

CREATE TABLE rc4 (

    a INT,

    b INT,

    c INT

)

PARTITION BY RANGE COLUMNS(a,b,c) (

    PARTITION p0 VALUES LESS THAN (0,25,50),

    PARTITION p1 VALUES LESS THAN (10,20,100),

    PARTITION p2 VALUES LESS THAN (10,30,50)

    PARTITION p3 VALUES LESS THAN (MAXVALUE,MAXVALUE,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,

store_id INT

)

PARTITION BY HASH(store_id)

PARTITIONS 4;

限制:

分区键必须是数字类型(integer)

分区键必须是主键和所有唯一键的一部分

需要指定分区数,否则默认是1

数据放入哪个分区是固定且可以提前计算的。比如:

CREATE TABLE t1 (col1 INT, col2 CHAR(5), col3 DATE)

    PARTITION BY HASH( YEAR(col3) )

    PARTITIONS 4;

如果col3的值为'2005-09-15',数据放入哪个分区的计算公式为:

MOD(YEAR('2005-09-01'),4)

=  MOD(2005,4)

=  1

即放入第一个分区

线性分区(LINER HASH PARTITION),与普通hash分区的区别是其采用线性二次幂算法,公式为:

V = POWER(2, CEILING(LOG(2, num)))

语句举例:

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分区类似,只是算法不同。对于NDB cluster,使用md5()函数,其他引擎使用类似password()函数进行分区。

举例:

CREATE TABLE tm1 (

    s1 CHAR(32) PRIMARY KEY

)

PARTITION BY KEY(s1)

PARTITIONS 10;

key键必须是主键的一部分。当存在主键或非空唯一键时,也可以为空。

复合分区/子分区

mysql5.7中分区类型为range或list,子分区可以使用hash或key分区。

有以下限制:

每个分区中的子分区数量必须一样;

子分区名称不能重复;

################################

分区表中NULL的处理

在range分区表中,NULL被认为小于所有值,被存放在第一个分区中;

LIST分区表中,必须指定某个分区包含NULL值;

在hash或key分区表中,NULL被当作0处理。

#############################

分区管理

range和list分区表可以进行分区的增、删、合并、拆分操作

增删分区的逻辑和写法与oracle基本一致。拆分/分裂分区的语法:

ALTER TABLE members

REORGANIZE PARTITION p0 INTO (

PARTITION n0 VALUES LESS THAN (1970),

PARTITION n1 VALUES LESS THAN (1980)

);

hash和key分区表不能进行删除,但可以合并,如:

ALTER TABLE clients COALESCE PARTITION 4;

其中4是待删除的分区数量。

添加6个分区分区,如:

ALTER TABLE clients ADD PARTITION PARTITIONS 6;

分区交换(用于range分区或子分区)

类似oracle,对分区表的某个分区与普通表进行交换。例如:

ALTER TABLE pt EXCHANGE PARTITION p WITH TABLE nt;

限制:

表结构一致,包含索引一致

普通表不包含外键,也不被其他表做外键引用

普通表数据的范围没有超过分区表定义

如果是innodb引擎,要求row格式一致

未使用data directory选项

需要表的增删改查权限

该过程不会触发触发器

交换时自增值会被重置

ignore选项无效

使用without validation选项时,不再逐条校验数据

分区重建,相当于删除所有数据再重新插入:

ALTER TABLE t1 REBUILD PARTITION p0, p1;

##############################################

分区的维护

优化分区,用于对大量数据进行修改或删除操作后,可以回收空间并整理碎片

相当于运行了check partition、analyze partition、repair partition。

可以对多个分区一次性执行:

alter table t1 optimize partition p0,p1;

注意:innodb不支持单个分区的optimize操作,会升级为对全表的重建,如:

mysql> alter table t4 optimize partition p1;

+-------+----------+----------+---------------------------------------------------------------------------------------------+

| Table | Op       | Msg_type | Msg_text                                                                                    |

+-------+----------+----------+---------------------------------------------------------------------------------------------+

| tl.t4 | optimize | note     | Table does not support optimize on partitions. All partitions will be rebuilt and analyzed. |

| tl.t4 | optimize | status   | OK                                                                                          |

+-------+----------+----------+---------------------------------------------------------------------------------------------+

2 rows in set (4.00 sec)

可以使用ALTER TABLE ... REBUILD PARTITION和ALTER TABLE ... ANALYZE PARTITION 进行替代,避免此问题。

分析分区,读取和存储分区的关键属性信息:

alter table t1 analyze partition p3;

修复分区

alter table t1 repair partition p0,p1;

正常执行时如果有重复键值会报错;

从5.7.2开始,可以使用alter ignore table选项,出现重复值时自动删除

检查分区

alter table trb3 check partition p1;

检查p1分区的数据和索引是否有中断。如果有重复值,则check操作会报错。

从5.7.2开始,可以使用alter ignore table选项,出现重复值时报告出来。

########################################################

获取分区信息

show create table

show table status =>是否分区

information_schema.partitions

explain select

举例:

mysql> show table status from tl like 't%'

    -> ;

+------+--------+---------+------------+------+----------------+-------------+-----------------+--------------+-----------+----------------+---------------------+---------------------+------------+-----------------+----------+----------------+---------+

| Name | Engine | Version | Row_format | Rows | Avg_row_length | Data_length | Max_data_length | Index_length | Data_free | Auto_increment | Create_time         | Update_time         | Check_time | Collation       | Checksum | Create_options | Comment |

+------+--------+---------+------------+------+----------------+-------------+-----------------+--------------+-----------+----------------+---------------------+---------------------+------------+-----------------+----------+----------------+---------+

| t1   | InnoDB |      10 | Dynamic    |    0 |              0 |       65536 |               0 |        65536 |         0 |              1 | 2020-06-18 15:35:43 | NULL                | NULL       | utf8_general_ci |     NULL | partitioned    |         |

| t2   | InnoDB |      10 | Dynamic    |   12 |           6826 |       81920 |               0 |        81920 |         0 |             30 | 2020-06-18 15:57:08 | 2020-06-18 16:01:59 | NULL       | utf8_general_ci |     NULL | partitioned    |         |

| t3   | InnoDB |      10 | Dynamic    |    9 |           1820 |       16384 |               0 |        16384 |         0 |              1 | 2020-06-18 15:55:24 | 2020-06-18 16:01:59 | NULL       | utf8_general_ci |     NULL |                |         |

| t4   | InnoDB |      10 | Dynamic    |   21 |           3900 |       81920 |               0 |        81920 |         0 |             30 | 2020-06-19 18:23:20 | NULL                | NULL       | utf8_general_ci |     NULL | partitioned    |         |

| t5   | InnoDB |      10 | Dynamic    |    0 |              0 |       49152 |               0 |        49152 |         0 |             30 | 2020-06-18 16:20:24 | 2020-06-18 16:27:30 | NULL       | utf8_general_ci |     NULL | partitioned    |         |

| tt   | InnoDB |      10 | Dynamic    |    3 |           5461 |       16384 |               0 |            0 |         0 |           NULL | 2020-06-17 23:23:00 | 2020-06-17 23:28:35 | NULL       | utf8_general_ci |     NULL |                |         |

+------+--------+---------+------------+------+----------------+-------------+-----------------+--------------+-----------+----------------+---------------------+---------------------+------------+-----------------+----------+----------------+---------+


推荐阅读
  • 本文介绍了游标的使用方法,并以一个水果供应商数据库为例进行了说明。首先创建了一个名为fruits的表,包含了水果的id、供应商id、名称和价格等字段。然后使用游标查询了水果的名称和价格,并将结果输出。最后对游标进行了关闭操作。通过本文可以了解到游标在数据库操作中的应用。 ... [详细]
  • 模板引擎StringTemplate的使用方法和特点
    本文介绍了模板引擎StringTemplate的使用方法和特点,包括强制Model和View的分离、Lazy-Evaluation、Recursive enable等。同时,还介绍了StringTemplate语法中的属性和普通字符的使用方法,并提供了向模板填充属性的示例代码。 ... [详细]
  • HashMap的相关问题及其底层数据结构和操作流程
    本文介绍了关于HashMap的相关问题,包括其底层数据结构、JDK1.7和JDK1.8的差异、红黑树的使用、扩容和树化的条件、退化为链表的情况、索引的计算方法、hashcode和hash()方法的作用、数组容量的选择、Put方法的流程以及并发问题下的操作。文章还提到了扩容死链和数据错乱的问题,并探讨了key的设计要求。对于对Java面试中的HashMap问题感兴趣的读者,本文将为您提供一些有用的技术和经验。 ... [详细]
  • MySQL多表数据库操作方法及子查询详解
    本文详细介绍了MySQL数据库的多表操作方法,包括增删改和单表查询,同时还解释了子查询的概念和用法。文章通过示例和步骤说明了如何进行数据的插入、删除和更新操作,以及如何执行单表查询和使用聚合函数进行统计。对于需要对MySQL数据库进行操作的读者来说,本文是一个非常实用的参考资料。 ... [详细]
  • 计算机存储系统的层次结构及其优势
    本文介绍了计算机存储系统的层次结构,包括高速缓存、主存储器和辅助存储器三个层次。通过分层存储数据可以提高程序的执行效率。计算机存储系统的层次结构将各种不同存储容量、存取速度和价格的存储器有机组合成整体,形成可寻址存储空间比主存储器空间大得多的存储整体。由于辅助存储器容量大、价格低,使得整体存储系统的平均价格降低。同时,高速缓存的存取速度可以和CPU的工作速度相匹配,进一步提高程序执行效率。 ... [详细]
  • 高质量SQL书写的30条建议
    本文提供了30条关于优化SQL的建议,包括避免使用select *,使用具体字段,以及使用limit 1等。这些建议是基于实际开发经验总结出来的,旨在帮助读者优化SQL查询。 ... [详细]
  • 本文讨论了clone的fork与pthread_create创建线程的不同之处。进程是一个指令执行流及其执行环境,其执行环境是一个系统资源的集合。在调用系统调用fork创建一个进程时,子进程只是完全复制父进程的资源,这样得到的子进程独立于父进程,具有良好的并发性。但是二者之间的通讯需要通过专门的通讯机制,另外通过fork创建子进程系统开销很大。因此,在某些情况下,使用clone或pthread_create创建线程可能更加高效。 ... [详细]
  • Oracle seg,V$TEMPSEG_USAGE与Oracle排序的关系及使用方法
    本文介绍了Oracle seg,V$TEMPSEG_USAGE与Oracle排序之间的关系,V$TEMPSEG_USAGE是V_$SORT_USAGE的同义词,通过查询dba_objects和dba_synonyms视图可以了解到它们的详细信息。同时,还探讨了V$TEMPSEG_USAGE的使用方法。 ... [详细]
  • 在Xamarin XAML语言中如何在页面级别构建ControlTemplate控件模板
    本文介绍了在Xamarin XAML语言中如何在页面级别构建ControlTemplate控件模板的方法和步骤,包括将ResourceDictionary添加到页面中以及在ResourceDictionary中实现模板的构建。通过本文的阅读,读者可以了解到在Xamarin XAML语言中构建控件模板的具体操作步骤和语法形式。 ... [详细]
  • MyBatis多表查询与动态SQL使用
    本文介绍了MyBatis多表查询与动态SQL的使用方法,包括一对一查询和一对多查询。同时还介绍了动态SQL的使用,包括if标签、trim标签、where标签、set标签和foreach标签的用法。文章还提供了相关的配置信息和示例代码。 ... [详细]
  • JDK源码学习之HashTable(附带面试题)的学习笔记
    本文介绍了JDK源码学习之HashTable(附带面试题)的学习笔记,包括HashTable的定义、数据类型、与HashMap的关系和区别。文章提供了干货,并附带了其他相关主题的学习笔记。 ... [详细]
  • 本文介绍了一个适用于PHP应用快速接入TRX和TRC20数字资产的开发包,该开发包支持使用自有Tron区块链节点的应用场景,也支持基于Tron官方公共API服务的轻量级部署场景。提供的功能包括生成地址、验证地址、查询余额、交易转账、查询最新区块和查询交易信息等。详细信息可参考tron-php的Github地址:https://github.com/Fenguoz/tron-php。 ... [详细]
  • GreenDAO快速入门
    前言之前在自己做项目的时候,用到了GreenDAO数据库,其实对于数据库辅助工具库从OrmLite,到litePal再到GreenDAO,总是在不停的切换,但是没有真正去了解他们的 ... [详细]
  • 本文介绍了如何使用PHP代码将表格导出为UTF8格式的Excel文件。首先,需要连接到数据库并获取表格的列名。然后,设置文件名和文件指针,并将内容写入文件。最后,设置响应头部,将文件作为附件下载。 ... [详细]
  • MySQL外键1对多问题的解决方法及实例
    本文介绍了解决MySQL外键1对多问题的方法,通过准备数据、创建表和设置外键关联等步骤,实现了用户分组和插入数据的功能。详细介绍了数据准备的过程和外键关联的设置,以及插入数据的示例。 ... [详细]
author-avatar
Q小泓别_431
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有