MySql分(fēn)表、分(fēn)庫、分(fēn)片和分(fēn)區知(zhī)識深入詳解

這篇文章主要介紹了MySql分(fēn)表、分(fēn)庫、分(fēn)片和分(fēn)區知(zhī)識深入詳解,如果有并發場景和數據量較大(dà)的場景的可以看一(yī)下(xià)文章,對你會有或多或少的幫助

一(yī)、前言

數據庫的數據量達到一(yī)定程度之後,爲避免帶來系統性能上的瓶頸。需要進行數據的處理,采用的手段是分(fēn)區、分(fēn)片、分(fēn)庫、分(fēn)表。

二、分(fēn)片(類似分(fēn)庫)

分(fēn)片是把數據庫橫向擴展(Scale Out)到多個物(wù)理節點上的一(yī)種有效的方式,其主要目的是爲突破單節點數據庫服務器的 I/O 能力限制,解決數據庫擴展性問題。Shard這個詞的意思是“碎片”。如果将一(yī)個數據庫當作一(yī)塊大(dà)玻璃,将這塊玻璃打碎,那麽每一(yī)小(xiǎo)塊都稱爲數據庫的碎片(DatabaseShard)。将整個數據庫打碎的過程就叫做分(fēn)片,可以翻譯爲分(fēn)片。

形式上,分(fēn)片可以簡單定義爲将大(dà)數據庫分(fēn)布到多個物(wù)理節點上的一(yī)個分(fēn)區方案。每一(yī)個分(fēn)區包含數據庫的某一(yī)部分(fēn),稱爲一(yī)個片,分(fēn)區方式可以是任意的,并不局限于傳統的水平分(fēn)區和垂直分(fēn)區。一(yī)個分(fēn)片可以包含多個表的内容甚至可以包含多個數據庫實例中(zhōng)的内容。每個分(fēn)片被放(fàng)置在一(yī)個數據庫服務器上。一(yī)個數據庫服務器可以處理一(yī)個或多個分(fēn)片的數據。系統中(zhōng)需要有服務器進行查詢路由轉發,負責将查詢轉發到包含該查詢所訪問數據的分(fēn)片或分(fēn)片集合節點上去(qù)執行。

三、Scale Out/Scale Up 和 垂直切分(fēn)/水平拆分(fēn)

Mysql的擴展方案包括Scale Out和Scale Up兩種。

Scale Out(橫向擴展)是指Application可以在水平方向上擴展。一(yī)般對數據中(zhōng)心的應用而言,Scale out指的是當添加更多的機器時,應用仍然可以很好的利用這些機器的資(zī)源來提升自己的效率從而達到很好的擴展性。

Scale Up(縱向擴展)是指Application可以在垂直方向上擴展。一(yī)般對單台機器而言,Scale Up值得是當某個計算節點(機器)添加更多的CPU Cores,存儲設備,使用更大(dà)的内存時,應用可以很充分(fēn)的利用這些資(zī)源來提升自己的效率從而達到很好的擴展性。

MySql的Sharding策略包括垂直切分(fēn)和水平切分(fēn)兩種。

垂直(縱向)拆分(fēn):是指按功能模塊拆分(fēn),以解決表與表之間的io競争。比如分(fēn)爲訂單庫、商(shāng)品庫、用戶庫...這種方式多個數據庫之間的表結構不同。

水平(橫向)拆分(fēn):将同一(yī)個表的數據進行分(fēn)塊保存到不同的數據庫中(zhōng),來解決單表中(zhōng)數據量增長出現的壓力。這些數據庫中(zhōng)的表結構完全相同。

表結構設計垂直切分(fēn)。常見的一(yī)些場景包括

a).大(dà)字段的垂直切分(fēn)。單獨将大(dà)字段建在另外(wài)的表中(zhōng),提高基礎表的訪問性能,原則上在性能關鍵的應用中(zhōng)應當避免數據庫的大(dà)字段

b). 按照使用用途垂直切分(fēn)。例如企業物(wù)料屬性,可以按照基本屬性、銷售屬性、采購屬性、生(shēng)産制造屬性、财務會計屬性等用途垂直切分(fēn)

c). 按照訪問頻(pín)率垂直切分(fēn)。例如電(diàn)子商(shāng)務、Web 2.0系統中(zhōng),如果用戶屬性設置非常多,可以将基本、使用頻(pín)繁的屬性和不常用的屬性垂直切分(fēn)開(kāi)

表結構設計水平切分(fēn)。常見的一(yī)些場景包括

a). 比如在線電(diàn)子商(shāng)務網站,訂單表數據量過大(dà),按照年度、月度水平切分(fēn)

b). Web 2.0網站注冊用戶、在線活躍用戶過多,按照用戶ID範圍等方式,将相關用戶以及該用戶緊密關聯的表做水平切分(fēn)

c). 例如論壇的置頂帖子,因爲涉及到分(fēn)頁問題,每頁都需要顯示置頂貼,這種情況可以把置頂貼水平切分(fēn)開(kāi)來,避免取置頂帖子時從所有帖子的表中(zhōng)讀取

四、分(fēn)表和分(fēn)區

分(fēn)表從表面意思說就是把一(yī)張表分(fēn)成多個小(xiǎo)表,分(fēn)區則是把一(yī)張表的數據分(fēn)成N多個區塊,這些區塊可以在同一(yī)個磁盤上,也可以在不同的磁盤上。

分(fēn)表和分(fēn)區的區别

1,實現方式上

mysql的分(fēn)表是真正的分(fēn)表,一(yī)張表分(fēn)成很多表後,每一(yī)個小(xiǎo)表都是完正的一(yī)張表,都對應三個文件(MyISAM引擎:一(yī)個.MYD數據文件,.MYI索引文件,.frm表結構文件)。

2,數據處理上

分(fēn)表後數據都是存放(fàng)在分(fēn)表裏,總表隻是一(yī)個外(wài)殼,存取數據發生(shēng)在一(yī)個一(yī)個的分(fēn)表裏面。分(fēn)區則不存在分(fēn)表的概念,分(fēn)區隻不過把存放(fàng)數據的文件分(fēn)成了許多小(xiǎo)塊,分(fēn)區後的表還是一(yī)張表,數據處理還是由自己來完成。

3,提高性能上

分(fēn)表後,單表的并發能力提高了,磁盤I/O性能也提高了。分(fēn)區突破了磁盤I/O瓶頸,想提高磁盤的讀寫能力,來增加mysql性能。

在這一(yī)點上,分(fēn)區和分(fēn)表的測重點不同,分(fēn)表重點是存取數據時,如何提高mysql并發能力上;而分(fēn)區呢,如何突破磁盤的讀寫能力,從而達到提高mysql性能的目的。

4,實現的難易度上

分(fēn)表的方法有很多,用merge來分(fēn)表,是最簡單的一(yī)種方式。這種方式和分(fēn)區難易度差不多,并且對程序代碼來說可以做到透明的。如果是用其他分(fēn)表方式就比分(fēn)區麻煩了。分(fēn)區實現是比較簡單的,建立分(fēn)區表,跟建平常的表沒什麽區别,并且對代碼端來說是透明的。

分(fēn)區的适用場景

1. 一(yī)張表的查詢速度已經慢(màn)到影響使用的時候。

2.表中(zhōng)的數據是分(fēn)段的

3.對數據的操作往往隻涉及一(yī)部分(fēn)數據,而不是所有的數據

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
CREATE TABLE sales (
 
    id INT AUTO_INCREMENT,
 
    amount DOUBLE NOT NULL,
 
    order_day DATETIME NOT NULL,
 
    PRIMARY KEY(id, order_day)
 
) ENGINE=Innodb
 
PARTITION BY RANGE(YEAR(order_day)) (
 
    PARTITION p_2010 VALUES LESS THAN (2010),
 
    PARTITION p_2011 VALUES LESS THAN (2011),
 
    PARTITION p_2012 VALUES LESS THAN (2012),
 
PARTITION p_catchall VALUES LESS THAN MAXVALUE);

分(fēn)表的适用場景

1. 一(yī)張表的查詢速度已經慢(màn)到影響使用的時候。

2.當頻(pín)繁插入或者聯合查詢時,速度變慢(màn)。

分(fēn)表的實現需要業務結合實現和遷移,較爲複雜(zá)。

五、分(fēn)表與分(fēn)庫

分(fēn)表能夠解決單表數據量過大(dà)帶來的查詢效率下(xià)降的問題,但是,卻無法給數據庫的并發處理能力帶來質的提升。面對高并發的讀寫訪問,當數據庫master服務器無法承載寫操作壓力時,不管如何擴展slave服務器,此時都沒有意義了。因此,我(wǒ)們必須換一(yī)種思路,對數據庫進行拆分(fēn),從而提高數據庫寫入能力,這就是所謂的分(fēn)庫。

與分(fēn)表策略相似,分(fēn)庫可以采用通過一(yī)個關鍵字取模的方式,來對數據訪問進行路由,如下(xià)圖所示
MySql分(fēn)表、分(fēn)庫、分(fēn)片和分(fēn)區知(zhī)識深入詳解
 

六、分(fēn)區與分(fēn)片區别

MySql分(fēn)表、分(fēn)庫、分(fēn)片和分(fēn)區知(zhī)識深入詳解