掌握数据库的大数据处理方案和HAsql
掌握为何须要数据库中间件,何为数据库中间件数据库
掌握不一样场景所需的数据库中间件特性缓存
掌握数据库中间件设计要点服务器
何为大数据并发
数据不少,数据量很大,记录数通常在千万级或者亿级甚至更多; 存储体量通常在TB级甚至PB级以上。 存储在一个或多个服务器上;less
跟“大数据”的区别机器学习
“大数据”指的是对大数据量进行分析和挖掘,发掘出数据中蕴含的有意义的东西,好比:规律、趋势、 喜爱等,并据此作出必定的推理和预测。 一般会涉及数据仓库、数据挖掘、人工智能AI、机器学习等方面的技术。分布式
大数据量带来的影响函数
服务端应用在处理业务逻辑时,会屡次操做数据,若是数据量太大,每次对数据进行操做会消耗大量的资源, 性能也比较低下,从而致使整个应用性能降低。高并发
大数据量带来的问题
慢:业务处理变慢、响应时间变慢、整个应用变慢; 高并发下屡次操做致使数据库崩溃
大数据量问题的本质就是:要操做的数据的基数太大
联机事务处理(OLTP)
面向交易的处理系统,特征是数据须要当即传送到计算中心进行处理,并在短期内给出处理结果
联机分析处理(OLAP)
经过多维的方式对数据进行分析、查询、报表,没必要要即时给出响应结果
分流
用和不用、经常使用和不经常使用分开
对数据库存放的数据:分区、分库、分表
对文件存放的数据:拆文件
考虑分批处理
原则就是:尽可能使每次操做的数据的基数减小
处理优化
优化Sql
考虑使用临时表、中间表
缓存技术
读多写少用缓存
合理使用NoSql
Mongodb、Redis、HBase等
数据库优化
合理设计数据库结构
合理构建索引
数据库集群
分布式大数据处理方案
Hadoop、Spark、Storm等
传统数据库
Oracle、MySQL、SQLServer、DB2
NoSql数据库
临时性键值存储:Redis、Memcached
永久性键值存储:ROMA、Redis
面向文档存储:mongoDB、CouchDB
面向列存储:Cassandra、HBase
所谓分区就是将一个表分解成多个区块进行操做和保存,从而下降每次操做的数据,提升性能。
而对应用来讲是透明的,从逻辑上看是只有一个表(这里跟分库分表的访问不同),但在物理上这个表多是由多个物理分区组成的,每一个分区都是一个独立的对象,能够进行独立处理
优势
• 进行逻辑数据分割,分割数据可以有多个不一样的物理文件路径
• 能够存储更多的数据,突破系统单个文件最大限制
• 提高性能,提升每一个分区的读写速度,提升分区范围查询的速度
• 能够经过删除相关分区来快速删除数据
• 经过跨多个磁盘来分散数据查询,从而提升磁盘I/O的性能
• 涉及到例如SUM()和COUNT()这样聚合函数的查询,能够很容易地进行并行处理
• 能够备份和恢复独立的分区,这对大数据量颇有好处
分区能支持的引擎
MySQL支持大部分的存储引擎建立分区,如MyISAM、InnoDB等;
不支持MERGE和CSV等来建立分区。
同一个分区表中的全部分区必须是同一个存储引擎。
Ø RANGE分区:一个给定连续区间的列值
Ø LIST分区:LIST是列值匹配一个离散值集合中的某个值来进行选择
Ø HASH分区:用户定义的表达式的返回值来进行hash计算以后选择的分区,该表达式使用将要插入到表中的这些行的列值进行计算,这个函数必须产生非负整数值
Ø KEY分区:相似于按HASH分区,由MySQL服务器提供其自身的哈希函数
1:若是表中存在primary key或者unique key时,分区的列是两种中的一个组成部分
2:若是表中不存在任何的primary key或者unique key,则能够指定任何一个列做为分区列
3:5.5版本前的Range、List、Hash分区要求分区键必须是int;MySQL5.5及以上,支持非整型的Range和List分区,即:range columns 和list columns。
分区命名
Ø 分区的名字基本上遵循其余MySQL标识符应当遵循的原则,例如用于表和数据库名字的标识符。可是应当注意,分区的名字是不区分大小写的。
Ø 不管使用何种类型的分区,分区老是在建立时就自动的顺序编号,且从0开始记录。
MySQL分区处理NULL值的方式
MySQL中的分区在禁止空值NULL上没有进行处理,不管它是一个列值仍是一个用户定义表达式的值,通常而言,在这种状况下MySQL把NULL视为0。若是你但愿回避这种作法,应该在设计表时声明列“NOT NULL”
能够对分区进行添加、删除、从新定义、合并或拆分等管理操做。
Ø 最大分区数目不能超过1024,通常建议对单表的分区数不要超过150个
Ø 若是含有惟一索引或者主键,则分区列必须包含在全部的惟一索引或者主键以内
Ø 不支持外键
Ø 不支持全文索引,对分区表的分区键建立索引,那么这个索引也将被分区
Ø 按日期进行分区很合适,由于不少日期函数能够用。可是对于字符串来讲合适的分区函数不太多
Ø 只有RANG和LIST分区能进行子分区,HASH和KEY分区不能进行子分区
Ø 分区表对于单条记录的查询没有优点
Ø 要注意选择分区的成本,每插入一行数据都须要按照表达式筛选插入的分区
Ø 分区字段尽可能不要能够为null
# 环境 MySQL5.7 Centos7 # 查看是否支持分区 **从MySQL5.1开始引入分区功能,用以下方式查看是否支持:** “老”的版本用 ``` SHOW VARIABLES LIKE ‘%partition%’; ``` 新的版本用 ``` show plugins; ``` 查看支持的存储引擎 ``` show engines; ``` # 建立分区 ## 1 建立RANGE分区 ``` CREATE TABLE tbl_users1 ( uuid INT NOT NULL, name VARCHAR(20), registerTime VARCHAR(100) ) PARTITION BY RANGE (uuid) ( PARTITION p0 VALUES LESS THAN (5), PARTITION p1 VALUES LESS THAN (10), PARTITION p2 VALUES LESS THAN (15), PARTITION p3 VALUES LESS THAN MAXVALUE ); ``` ### 1.1 添加数据和测试 ``` show tables; insert into tbl_users1 values(1,'x','2001-01-01'); insert into tbl_users1 values(8,'x','2001-01-02'); insert into tbl_users1 values(80,'x','2001-01-03'); select * from tbl_users1; select * from tbl_users1 where uuid = 8; ``` 表看不出来有任何区别,并且执行插入语句的时候也没有任何影响,而后查询看出来对应用是透明的,可是没看出分区啊!那这个分区体如今哪里呢?参考最后分区位置和信息查看张姐 ## 2 建立List分区 ``` CREATE TABLE tbl_users2 ( uuid INT NOT NULL, name VARCHAR(20), registerTime VARCHAR(100) ) PARTITION BY List (uuid) ( PARTITION p0 VALUES in (1,2,3,5), PARTITION p1 VALUES in (7,9,10), PARTITION p2 VALUES in (11,15) ); ``` ### 2.1 添加数据和测试 ``` insert into tbl_users2 values(1,'x','2001-01-02'); insert into tbl_users2 values(2,'x','2001-01-03'); insert into tbl_users2 values(7,'x','2001-01-04'); select * from tbl_users2; select * from tbl_users2 where uuid = 1; select * from tbl_users2 partition(p0); select * from tbl_users2 partition(p1); select * from tbl_users2 partition(p2); ``` **(1)若是试图操做的列值不在分区值列表中时,那么会失败并报错。要注意的是,LIST分区没有相似如“VALUES LESS THAN MAXVALUE”这样的包含其余值在内的定义,将要匹配的任何值都必须在值列表中找到。** **(2)LIST分区除了能和RANGE分区结合起来生成一个复合的子分区,与HASH和KEY分区结合起来生成复合的子分区也是能够的。** ## 3 建立非整形的RANGE,LIST分区 ``` CREATE TABLE tbl_users3 ( uuid INT NOT NULL, name VARCHAR(20), registerTime VARCHAR(100) ) PARTITION BY RANGE columns (name) ( PARTITION p0 VALUES LESS THAN ('id05'), PARTITION p1 VALUES LESS THAN ('id10'), PARTITION p2 VALUES LESS THAN ('id15') ); ``` ### 3.1 添加数据和测试 ``` insert into tbl_users3 values(2,'id07','2001-01-01'); insert into tbl_users3 values(3,'id02','2001-01-01'); insert into tbl_users3 values(4,'id12','2001-01-01'); select * from tbl_users3; select * from tbl_users3 partition(p0); select * from tbl_users3 partition(p1); select * from tbl_users3 partition(p2); ``` ## 4 建立Hash分区 HASH分区主要用来确保数据在预先肯定数目的分区中平均分布。在RANGE和LIST分区中,必须明确指定一个给定的列值或列值集合以指定应该保存在哪一个分区中; 而在HASH分区中,MySQL自动完成这些工做,要作的只是基于将要被哈希的列值指定一个表达式,以及指定被分区的表将要被分割成的分区数量,如: ``` CREATE TABLE tbl_users4 ( uuid INT NOT NULL, name VARCHAR(20), registerTime VARCHAR(100) ) PARTITION BY HASH (uuid) //uuid能够添加表达式,好比/2,或者mod(uuid,2),性能低,每条数据要计算以后 在hash而后再插入 PARTITIONS 3; ``` (1)因为每次插入、更新、删除一行,这个表达式都要计算一次;这意味着很是复杂的表达式可能会引发性 能问题,尤为是在执行同时影响大量行的运算(例如批量插入)的时候。 (2)最有效率的哈希函数是只对单个表列进行计算,而且它的值随列值进行一致地增大或减少,由于这考虑了在分区范围上的“修剪”。也就是说,表达式值和它所基于的列的值变化越接近,就能越有效地使用该表达式来进行HASH分区。 ### 4.1 添加数据和测试 ``` insert into tbl_users4 values(10,'id7','2001-01-01'); insert into tbl_users4 values(11,'id07','2001-01-01'); insert into tbl_users4 values(12,'id02','2001-01-01'); select * from tbl_users4; select * from tbl_users4 where uuid = 10; select * from tbl_users4 where uuid = 11; select * from tbl_users4 where uuid = 12; select * from tbl_users4 partition(p0); select * from tbl_users4 partition(p1); select * from tbl_users4 partition(p2); ``` ### 4.2 线性Hash分区 线性哈希分区在“PARTITION BY” 子句中添加“LINEAR”关键字。 线性哈希分区的优势在于增长、删除、合并和拆分分区将变得更加快捷,有利于处理含有极其大量数据的表。它的缺点在于,各个分区间数据的分布不大可能均衡。 ## 5 Key分区 相似于按照HASH分区,Hash分区容许用户自定义的表达式,而Key分区不容许使用用户自定义的表达式; Hash分区只支持整数分区,Key分区支持除了blob或text类型以外的其余数据类型分区。 与Hash分区不一样,建立Key分区表的时候,能够不指定分区键,默认会选择使用主键或惟一键做为分区键,没有主键或惟一键,就必须指定分区键。 ``` CREATE TABLE tbl_users5 ( uuid INT NOT NULL, name VARCHAR(20), registerTime VARCHAR(100) ) PARTITION BY LINEAR Key (uuid) PARTITIONS 3; ``` ### 5.1 添加数据和测试 ``` insert into tbl_users5 values(12,'id7','2001-01-01'); insert into tbl_users5 values(7,'id07','2001-01-01'); select * from tbl_users5; explain partition select * from tbl_user5 where uuid = 12; //看看是key分区是如何分的? select * from tbl_users5 partition(p0); select * from tbl_users5 partition(p1); select * from tbl_users5 partition(p2); ``` ## 6 子分区(复合分区) 在每一个分区内,子分区的名字必须是惟一的,目前在整个表中,也要保持惟一。例如: ``` CREATE TABLE tbl_users6 ( uuid INT NOT NULL, name VARCHAR(20), registerTime Date ) PARTITION BY RANGE(YEAR(registerTime)) SUBPARTITION BY HASH(TO_DAYS(registerTime)) SUBPARTITONS 2 ( PARTITION p0 VALUES LESS THAN (2008), PARTITION p1 VALUES LESS THAN (2015), PARTITION p2 VALUES LESS THAN MAXVALUE ); ``` ### 6.1添加数据和测试 ``` insert into tbl_users6 values(1,'x','2007-01-02'); insert into tbl_users6 values(2,'x','2009-01-03'); insert into tbl_users6 values(3,'x','2016-01-04'); select * from tbl_users6; explain partition select * from tbl_user6 \G; //看看是子分区是如何分的? explain partition select * from tbl_user6 where registerTime='2007-01-02' \G; select * from tbl_users6 partition(p0); select * from tbl_users6 partition(p1); select * from tbl_users6 partition(p2); ``` # 分区管理 ## 1 RANGE和LIST分区的管理 ### 1.1 删除 删除分区语句如: ``` show create table 'tbl_users1' \G; alter table tbl_users1 drop partition p0; select * from tbl_user1; ``` (1)当删除了一个分区,也同时删除了该分区中全部的数据 (2)能够经过show create table tbl_users1;来查看新的建立表的语句 (3)若是是List分区的话,删除的数据不能新增进来,由于这些行的列值包含在已 经删除了的分区的值列表中 ### 1.2 添加 添加分区语句如: ``` alter table tbl_users1 add partition(partition p4 values less than(50));//p3是最大值,因此不能添加p4 alter table tbl_users1 drop partition p3; //p3是最大值,因此不能添加p4 show create table 'tbl_users1' \G; //删除以后再看下分区 alter table tbl_users1 add partition(partition p4 values less than(50));//不能用p0 show create table 'tbl_users1' \G; //添加以后再看下分区 ``` (1)对于RANGE分区的表,只能够添加新的分区到分区列表的高端 (2)对于List分区的表,不能添加已经包含在现有分区值列表中的任意值 ### 1.3 重建(拆分合并)分区不丢失数据 若是但愿能不丢失数据的条件下从新定义分区,可使用以下语句: ``` ALTER TABLE tbl_name REORGANIZE PARTITION partition_list INTO (partition_definitions) ``` (1)拆分分区如: ``` alter table tbl_users1 REORGANIZE PARTITION p1 INTO(partition s0 values less than(5), partition s1 values less than(10)); show create table 'tbl_users1' \G; ``` 或者如(针对LIST): ``` alter table tbl_users2 REORGANIZE PARTITION p0 INTO(partition s0 values in(1,2,3), partition s1 values in(4,5)); show create table 'tbl_users2' \G; select * from tbl_users2 //查看数据是否丢失 ``` (2)合并分区如: ``` alter table tbl_users2 REORGANIZE PARTITION s0,s1 INTO(partition p0 values in(1,2,3,4,5)); select * from tbl_users2 //查看数据是否丢失 show create table 'tbl_users2' \G; //在查看分区信息 ``` ### 1.4 删除分区不丢失数据 删除全部分区,但保留数据,形如: ``` show create table 'tbl_users1' \G; //在查看分区信息 alter table tbl_users1 remove partitioning; show create table 'tbl_users1' \G; //没有分区信息了 select * from tbl_users1 //查看数据是否丢失 ``` ## 2 HASH和KEY分区的管理 ### 2.1 减小分区数量 减小分区数量语句如: ``` show create table 'tbl_users4' \G; //先看分区数量 alter table tbl_users4 COALESCE PARTITION 1; show create table 'tbl_users4' \G; //减小再看分区数量 ``` ### 2.2 添加分区数量 添加分区数量语句如: ``` alter table tbl_users4 add PARTITION partitions 2; show create table 'tbl_users4' \G; //添加再看分区数量 ``` ## 3 其余分区管理 ### 3.1:重建分区 相似于先删除保存在分区中的全部记录,而后从新插入它们,可用于整理分区碎片。如: ``` alter table tbl_users REBUILD PARTITION p2,p3; ``` ### 3.2:优化分区 若是从分区中删除了大量的行,或者对一个带有可变长度的行(也就是说,有VARCHAR,BLOB,或TEXT类型的列)做了许多修改,可使用“ALTER TABLE ... OPTIMIZE PARTITION”来收回没有使用的空间,并整理分区数据文件的碎片。如: ``` alter table tbl_users OPTIMIZE PARTITION p2,p3; ``` ### 3.3:分析分区 读取并保存分区的键分布,如: ``` alter table tbl_users ANALYZE PARTITION p2,p3; ``` ### 3.4:检查分区 检查分区中的数据或索引是否已经被破坏,如: ``` alter table tbl_users CHECK PARTITION p2,p3; ``` ### 3.5:修补分区 修补被破坏的分区,如: ``` alter table tbl_users REPAIR PARTITION p2,p3; ``` # 分区位置查看 ## 到存放数据的地方查看文件,路经配置在 ``` show global variables like "%datadir%"; cd 到数据库 ``` frm:表结构 ibd:索引和数据文件 看到咱们的苍老师了吗?看到咱们的小泽玛利亚老师了吗? ## 能够经过下面的语句来查看表的分区信息: ``` select * from information_schema.partitions where table_schema=‘xxx’ and table_name=‘xxx’ \G; ``` \G:按列显示 ## 能够经过下面的语句来查看分区上的数据 ``` select * from tbl_users partition(p0); ``` ## 可使用下面的语句来查看MySQL会操做的分区 ``` explain partitions select * from tbl_users where uuid=80; ``` explain:查询计划,分析性能用的