掌握數據庫的大數據處理方案和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:查詢計劃,分析性能用的