我们大家都知道通过MySQL数据库分区(Partition)可以提升MySQL数据库的性能,那么到底什么是MySQL数据库分区呢?以及其实际应用的好处的表现有哪些呢?以下的文章就是对这些内容的描述。

什么是数据库分区?

数据库分区是一种物理数据库设计技术,DBA和数据库建模人员对其相当熟悉。虽然分区技术可以实现很多效果,但其主要目的是为了在特定的SQL操作 中减少数据读写的总量以缩减响应时间。 分区主要有两种形式://这里一定要注意行和列的概念(row是行,column是列)

水平分区(Horizontal Partitioning) 这种形式分区是对表的行进行分区,通过这样的方式不同分组里面的物理列分割的数据集得以组合,从而进行个体分割(单分区)或集体分割(1个或多个分区)。 所有在表中定义的列在每个数据集中都能找到,所以表的特性依然得以保持。

举个简单例子:一个包含十年发票记录的表可以被MySQL数据库分区为十个不同的分区,每个分区包含的是其中一年的记录。(朋奕注:这里具体使用的分区方式我们后面再说,可以先说一点,一定要通过某个属性列来分割,譬如这里使用的列就是年份)

垂直分区(Vertical Partitioning) 这种分区方式一般来说是通过对表的垂直划分来减少目标表的宽度,使某些特定的列被划分到特定的分区,每个分区都包含了其中的列所对应的行。

举个简单例子:一个包含了大text和BLOB列的表,这些text和BLOB列又不经常被访问,这时候就要把这些不经常使用的text和BLOB了划分到另一个分区,在保证它们数据相关性的同时还能提高访问速度。

在数据库供应商开始在他们的数据库引擎中建立分区(主要是水平分区)时,DBA和建模者必须设计好表的物理分区结构,不要保存冗余的数据(不同表中 同时都包含父表中的数据)或相互联结成一个逻辑父对象(通常是视图)。这种做法会使水平分区的大部分功能失效,有时候也会对垂直分区产生影响。

在MySQL 5.1中进行分区

MySQL5.1中最激动人心的新特性应该就是对水平MySQL数据库分区的支持了。这对MySQL的使用者来说确实是个好消息,而且她已经支持分区大部分模式:

Range(范围) – 这种模式允许DBA将数据划分不同范围。例如DBA可以将一个表通过年份划分成三个分区,80年代(1980's)的数据,90年代(1990's)的数据以及任何在2000年(包括2000年)后的数据。

Hash(哈希) – 这中模式允许DBA通过对表的一个或多个列的Hash Key进行计算,最后通过这个Hash码不同数值对应的数据区域进行分区,。例如DBA可以建立一个对表主键进行分区的表。

Key(键值) – 上面Hash模式的一种延伸,这里的Hash Key是MySQL系统产生的。

List(预定义列表) – 这种模式允许系统通过DBA定义的列表的值所对应的行数据进行分割。例如:DBA建立了一个横跨三个分区的表,分别根据2004年2005年和2006年值所对应的数据。

Composite(复合模式) - 很神秘吧,哈哈,其实是以上模式的组合使用而已,就不解释了。举例:在初始化已经进行了Range范围分区的表上,我们可以对其中一个分区再进行hash哈希分区。

分区带来的两点好处:

性能的提升(Increased performance) -
在扫描操作中,如果MySQL的优化器知道哪个分区中才包含特定查询中需要的数据,它就能直接去扫描那些分区的数据,而不用浪费很多时间扫描不需要的地方
了。需要举个例子?好啊,百万行的表划分为10个分区,每个分区就包含十万行数据,那么查询分区需要的时间仅仅是全表扫描的十分之一了,很明显的对比。

同时对十万行的表建立索引的速度也会比百万行的快得多得多。如果你能把这些分区建立在不同的磁盘上,这时候的I/O读写速度就“不堪设想”(没用错词,真的太快了,理论上100倍的速度提升啊,这是多么快的响应速度啊,所以有点不堪设想了)了。

对数据管理的简化(Simplified data management) -
分区技术可以让DBA对数据的管理能力提升。通过优良的MySQL数据库分区,DBA可以简化特定数据操作的执行方式。例如:DBA在对某些分区的内容进
行删除的同时能保证余下的分区的数据完整性(这是跟对表的数据删除这种大动作做比较的)。
此外分区是由MySQL系统直接管理的,DBA不需要手工的去划分和维护。例如:这个例如没意思,不讲了,如果你是DBA,只要你划分了分区,以后你就不
用管了就是了。

站在性能设计的观点上,俺们对以上的内容也是相当感兴趣滴。通过使用分区和对不同的SQL操作的匹配设计,数据库的性能一定能获得巨大提升。下面咱们一起用用这个MySQL 5.1的新功能看看。

下面所有的测试都在Dell Optiplex box with a Pentium 4 3.00GHz processor, 1GB of RAM机器上(炫耀啊……),Fedora Core 4和MySQL 5.1.6 alpha上运行通过。

如何进行实际分区 看看分区的实际效果吧。我们建立几个同样的MyISAM引擎的表,包含日期敏感的数据,但只对其中一个分区。分区的表(表名为part_tab)我们采用Range范围分区模式,通过年份进行MySQL数据库分区:

  1. mysql> CREATE TABLE part_tab
  2. -> ( c1 int default NULL,
  3. -> c2 varchar(30) default NULL,
  4. -> c3 date default NULL ->
  5. -> ) engine=myisam
  6. -> PARTITION BY RANGE (year(c3))
  7. (PARTITION p0 VALUES LESS THAN (1995),
  8. -> PARTITION p1 VALUES LESS THAN (1996) , PARTITION p2 VALUES LESS THAN (1997) ,
  9. -> PARTITION p3 VALUES LESS THAN (1998) , PARTITION p4 VALUES LESS THAN (1999) ,
  10. -> PARTITION p5 VALUES LESS THAN (2000) , PARTITION p6 VALUES LESS THAN (2001) ,
  11. -> PARTITION p7 VALUES LESS THAN (2002) , PARTITION p8 VALUES LESS THAN (2003) ,
  12. -> PARTITION p9 VALUES LESS THAN (2004) , PARTITION p10 VALUES LESS THAN (2010),
  13. -> PARTITION p11 VALUES LESS THAN MAXVALUE );
  14. Query OK, 0 rows affected (0.00 sec)

注意到了这里的最后一行吗?这里把不属于前面年度划分的年份范围都包含了,这样才能保证数据不会出错,大家以后要记住啊,不然数据库无缘无故出错你就爽了。

那下面我们建立没有MySQL数据库分区的表(表名为no_part_tab):

  1. mysql> create table no_part_tab
  2. -> (c1 int(11) default NULL,
  3. -> c2 varchar(30) default NULL,
  4. -> c3 date default NULL)
  5. engine=myisam;
  6. Query OK, 0 rows affected (0.02 sec)

下面咱写一个存储过程它能向咱刚才建立的已分区的表中平均的向每个分区插入共8百万条不同的数据。填满后,咱就给没分区的克隆表中插入相同的数据:

  1. mysql> delimiter //
  2. mysql> CREATE PROCEDURE load_part_tab()
  3. -> begin
  4. -> declare v int default 0;
  5. -> while v < 8000000
  6. -> do
  7. -> insert into part_tab
  8. -> values (v,'testing partitions',adddate('1995-01-01',(rand(v)*36520) mod 3652));
  9. -> set vv = v + 1;
  10. -> end while;
  11. -> end
  12. -> //
  13. Query OK, 0 rows affected (0.00 sec)
  14. mysql> delimiter ;
  15. mysql> call load_part_tab();
  16. Query OK, 1 row affected (8 min 17.75 sec)
  17. mysql> insert into no_part_tab select * from part_tab;
  18. Query OK, 8000000 rows affected (51.59 sec) Records: 8000000 Duplicates: 0 Warnings: 0

表都准备好了。咱开始对这两表中的数据进行简单的范围查询吧。先分区了的,后没MySQL数据库分区的,跟着有执行过程解析(MySQL Explain命令解析器),可以看到MySQL做了什么:

  1. mysql> select count(*) from no_part_tab where
  2. -> c3 > date '1995-01-01' and c3 < date '1995-12-31';
  3. +----------+ | count(*) | +----------+ | 795181 | +----------+ 1 row in set (38.30 sec)
  4. mysql> select count(*) from part_tab where
  5. -> c3 > date '1995-01-01' and c3 < date '1995-12-31';
  6. +----------+ | count(*) | +----------+ | 795181 | +----------+ 1 row in set (3.88 sec)
  7. mysql> explain select count(*) from no_part_tab where
  8. -> c3 > date '1995-01-01' and c3 < date '1995-12-31'\G
  9. id: 1 select_type:
  10. SIMPLE table: no_part_tab
  11. type: ALL
  12. possible_keys: NULL
  13. key: NULL
  14. key_len: NULL
  15. ref: NULL
  16. rows: 8000000
  17. Extra: Using where 1 row in set (0.00 sec)
  18. mysql> explain partitions select count(*) from part_tab where
  19. -> c3 > date '1995-01-01' and c3 < date '1995-12-31'\G
  20. id: 1
  21. select_type: SIMPLE
  22. table: part_tab
  23. partitions: p1
  24. type: ALL
  25. possible_keys: NULL
  26. key: NULL
  27. key_len: NULL
  28. ref: NULL
  29. rows: 798458
  30. Extra: Using where 1 row in set (0.00 sec)

从上面结果可以容易看出,设计恰当表分区能比非分区的减少90%的响应时间。而命令解析Explain程序也告诉我们在对已分区的表的查询过程中仅对第一个分区进行了扫描,其他都跳过了。

哔厉吧拉,说阿说……反正就是这个分区功能对DBA很有用拉,特别对VLDB和需要快速反应的系统。

对Vertical Partitioning的一些看法 虽然MySQL 5.1自动实现了水平分区,但在设计数据库的时候不要轻视垂直MySQL数据库分区。虽然要手工去实现垂直分区,但在特定场合下你会收益不少的。例如在前 面建立的表中,VARCHAR字段是你平常很少引用的,那么对它进行垂直分区会不会提升速度呢?咱们看看测试结果:

  1. mysql> desc part_tab; +-------+-------------+------+-----+---------+-------+
  2. | Field | Type | Null | Key | Default | Extra | +-------+-------------+------+-----+---------+-------+
  3. | c1 | int(11) | YES | | NULL | |
  4. | c2 | varchar(30) | YES | | NULL | |
  5. | c3 | date | YES | | NULL | | +-------+-------------+------+-----+---------+-------+ 3 rows in set (0.03 sec)
  6. mysql> alter table part_tab drop column c2;
  7. Query OK, 8000000 rows affected (42.20 sec) Records: 8000000 Duplicates: 0 Warnings: 0
  8. mysql> desc part_tab; +-------+---------+------+-----+---------+-------+
  9. | Field | Type | Null | Key | Default | Extra | +-------+---------+------+-----+---------+-------+
  10. | c1 | int(11) | YES | | NULL | |
  11. | c3 | date | YES | | NULL | | +-------+---------+------+-----+---------+-------+
  12. 2 rows in set (0.00 sec)
  13. mysql> select count(*) from part_tab where
  14. -> c3 > date '1995-01-01' and c3 < date '1995-12-31'; +----------+
  15. | count(*) | +----------+
  16. | 795181 | +----------+
  17. 1 row in set (0.34 sec)

在设计上去掉了VARCHAR字段后,不止是你,俺也发现查询响应速度上获得了另一个90%的时间节省。所以大家在设计表的时候,一定要考虑,表中的字段是否真正关联,又是否在你的查询中有用?

补充说明

这么简单的文章肯定不能说全MySQL 5.1 分区机制的所有好处和要点(虽然对自己写文章水平很有信心),下面就说几个感兴趣的:

支持所有存储引擎(MyISAM, Archive, InnoDB, 等等)

对分区的表支持索引,包括本地索引local indexes,对其进行的是一对一的视图镜像,假设一个表有十个分区,那么其本地索引也包含十个分区。

关于分区的元数据Metadata的表可以在INFORMATION_SCHEMA数据库中找到,表名为PARTITIONS。

All SHOW 命令支持返回MySQL数据库分区表以及元数据的索引。

对其操作的命令和实现的维护功能有(比对全表的操作还多):

  1. ADD PARTITION
  2. DROP PARTITION
  3. COALESCE PARTITION
  4. REORGANIZE PARTITION
  5. ANALYZE PARTITION
  6. CHECK PARTITION
  7. OPTIMIZE PARTITION
  8. REBUILD PARTITION
  9. REPAIR PARTITION

以上的相关内容就是对MySQL数据库分区的介绍,望你能有所收获。

MySQL数据库分区的概念与2大好处(1)的更多相关文章

  1. mysql数据库分区功能及实例详解

    分区听起来怎么感觉是硬盘呀,对没错除了硬盘可以分区数据库现在也支持分区了,分区可以解决大数据量的处理问题,下面一起来看一个mysql数据库分区功能及实例详解   一,什么是数据库分区 前段时间写过一篇 ...

  2. mysql数据库数据(字段数过大)太多导入不了的解决方法

    mysql数据库数据(字段数过大)太多导入不了的决方法: 1.打开navicat 工具 2.在数据库上右键,执行右键菜单命令“命令列界面” 3.在打开的窗口中,运行set global max_all ...

  3. mysql数据库分区和分表

    转载自 https://www.cnblogs.com/miketwais/articles/mysql_partition.html https://blog.csdn.net/vbirdbest/ ...

  4. MySQL——数据库和 SQL 概念&&MySQL的安装

    数据库和 SQL 概念 数据库(Database)是按照数据结构来组织.存储和管理数据的仓库,它的产生距今已有六十多年.随着信息技术和市场的发展,数据库变得无处不在:它在电子商务.银行系统等众多领域都 ...

  5. Mysql数据库的基本概念和架构

    数据库 1.键:主键是表中的标志列.一个键可能由几列组成.可以使用键作为表格之间的引用. CustomerID是Customers表的主键,当它出现在其他表,例如Orders表中的时候就称它为外键. ...

  6. 什么是分表和分区 MySql数据库分区和分表方法

    1.为什么要分表和分区 日常开发中我们经常会遇到大表的情况,所谓的大表是指存储了百万级乃至千万级条记录的表.这样的表过于庞大,导致数据库在查询和插入的时候耗时太长,性能低下,如果涉及联合查询的情况,性 ...

  7. MySQL数据库1 - 基本概念及安装

    一.数据管理技术的产生和发展: 1.人工管理阶段 - 效率低,成本高(文字) 2.文件系统阶段 - 易于存储,处理速度快,数据形式丰富(文字,声音,图片...磁带,磁盘) 3.数据库系统阶段 - 易于 ...

  8. mysql数据库分区及测试

    1. 测试数据库是否支持分区 mysql可以通过下面语句判断是否支持分区: SHOW VARIABLES LIKE '%partition%'; 如果输出:have_partitioning   YE ...

  9. MySql数据库1【概念】

    [mysql] mysql是目前最主流的跨平台.开放源代码的关系型数据库,由瑞曲的mysql ab公司开发,已经被SUN公司收购,标识是一只名为sakila的海豚,代表mysql的速度.能力.精确优秀 ...

随机推荐

  1. 201521123050《Java程序设计》第1周学习总结

    1. 本周学习总结 java至今已经不仅是个程序语言,也代表了解决问题的平台,更代表原厂,各个厂商,社群,开发者与用户沟通的成果.若以程序语言来看待java,正如冰山一角,如此便看不到java身为程序 ...

  2. linux目录结构图

  3. 一步步带你做vue后台管理框架(三)——登录功能

    系列教程<一步步带你做vue后台管理框架>第三课 github地址:vue-framework-wz 线上体验地址:立即体验 <一步步带你做vue后台管理框架>第一课:介绍框架 ...

  4. 云计算之阿里仓库停止openstack mitaka源报错“No package centos-release-openstack-mitaka available.”

    之前学习了一个月的openstack的mitaka版本,写完脚本放置一段时间,最近准备正式部署突然发现 No package centos-release-openstack-mitaka avail ...

  5. CSS公用

    *{font-size: 100px;} body,span,h1,h2,h3,h4,h5,h6,li,ul,p,em,strong,ol,form,pre,input,article,header, ...

  6. [python学习笔记] pyinstaller打包pyqt5程序无法运行

    问题 pyinstaller打包的pyqt5程序在部分电脑上会失败.用户截图提示下边错误日志 无法定位程序输入点 ucrtbase.terminate 于动态链接库 api-ms-win-crt-ru ...

  7. XML的序列化(Serializer)

    步骤: //1获取XmlSerializer 类的实例 通过Xml这个工具类去获取 XmlSerializer xmlSerializer = Xml.newSerializer(); try { / ...

  8. PHP获取文件的绝对路径

    1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 ===========PH ...

  9. 我是如何利用Hadoop做大规模日志压缩的

    背景 刚毕业那几年有幸进入了当时非常热门的某社交网站,在数据平台部从事大数据开发相关的工作.从日志收集.存储.数据仓库建设.数据统计.数据展示都接触了一遍,比较早的赶上了大数据热这波浪潮.虽然今天的人 ...

  10. AngularJS -- Bootstrap(启动器)

    点击查看AngularJS系列目录 转载请注明出处:http://www.cnblogs.com/leosx/ Bootstrap(初始化) 这章介绍了Angular的初始化过程,以及如何在必要的时候 ...