MySQL分割槽和分表

2022-06-20 03:03:14 字數 3834 閱讀 1320

1.分割槽的型別:

(1)range:把連續區間按範圍劃分

例:

create table user(

id int(11),

money int(11) unsigned not null,

date datetime

)partition by range(year(date))(

partition p2014 values less than (2015),

partition p2015 values less than (2016),

partition p2016 values less than (2017),

partition p2017 values less than maxvalue

);

(2)list:把離散值分成集合,按集合劃分,適合有固定取值列的表

例:

create table user(

a int(11),

b int(11)

)partition by list(b)(

partition p0 values in (1,3,5,7,9),

partition p1 values in (2,4,6,8,0)

);

(3)hash:隨機分配,分割槽數固定

例:

create table user(

a int(11),

b datetime

)partition by hash(year(b))

partitions 4;

(4)key:類似hash,區別是只支援1列或多列,且mysql提供自身的hash函式

例:

create table user(

a int(11),

b datetime

)partition by key(b)

partitions 4;

2.分割槽管理

(1)新增分割槽

alter table sale_data

add partition (partition p201710 values less than (201711));

(2)刪除分割槽

--當刪除了乙個分割槽,也同時刪除了該分割槽中所有的資料。

alter table sale_data drop partition p201710;

(3)分割槽的合併

下面的sql,將p201701 - p201709 合併為3個分割槽p2017q1 - p2017q3

alter table sale_data

reorganize partition p201701,p201702,p201703,

p201704,p201705,p201706,

p201707,p201708,p201709 into

( partition p2017q1 values less than (201704),

partition p2017q2 values less than (201707),

partition p2017q3 values less than (201710)

);

3.分割槽應該注意的事項:

(1)做分割槽時,要麼不定義主鍵,要麼把分割槽字段加入到主鍵中。

(2)分割槽字段不能為null,要不然怎麼確定分割槽範圍呢,所以盡量not null

1.垂直分表

把原來有很多列的表拆分成多個表,原則是:

(1)把常用、不常用的字段分開放

(2)把大字段獨立存放在乙個表中

2.水平分表

為了解決單錶資料量過大的問題,每個水平拆分表的結構完全一致。

例:(1)按時間結構

如果業務系統對時效性較高,比如新聞發布系統的文章表,可以把資料庫設計成時間結構,按時間分有幾種結構:

(a)平板式

表類似:

article_201701

article_201702

article_201703

用年來分還是用月可自定,但用日期的話表就太多了,也沒這必要。一般建議是按月分就可以。

這種分法,其難處在於,假設我要列20條資料,結果這三張表裡都有2條,那麼業務上很有可能要求讀三次表。如果時間長了,有幾十張表,而每張表是0條,那不就是要讀完整個系統的表才行麼?另外這個結構,要作分頁是比較難實現的。

主鍵:在這個系統中,主鍵是13位帶毫秒的時間戳,不要用自動編號,否則難以通過主鍵定位到表,也可以在查詢時帶上時間,但比較煩瑣。

(b)歸檔式

表類似:

article_old

article_new

為了解決平板式的缺點,可以採用時間歸檔式設計,可以看到這個系統只有兩張表。一張是舊文章表,一張是新文章表,新文章表放2個月的資訊,每天定期把2

個月中的最早一天的文章歸入舊表中。這樣一方面可以解決效能問題,因為一般新聞發布系統讀取的都是新的內容,舊的內容讀取少;第二可以委婉地解決功能問

題,比如平板式所說的問題,在歸檔式中最多也只需要讀2張表就完成了。

歸檔式的缺點在於舊表容量還是相對比較大,如果業務允許,可對舊表中的超舊內容進行再歸檔或直接清理掉。

(2)按版塊結構

如果按照文章的所屬版塊進行拆表,比如新聞、體育版塊拆表,一方面可以使每個表資料量分離,另一方面是各版塊之間相互影響可降到最低。假如新聞版塊的資料表損壞或需要維護,並不會影響到體育版塊的正常工作,從而降低了風險。版塊結構同時常用於bbs這樣的系統。

板塊結構也有幾種分法:

(a)對應式

對於版塊數量不多,而且較為固定的形式,就直接對應就好。比如新聞版塊,可以分出新聞的目錄表,新聞的文章表等。

news_category

news_article

sports_category

sports_article

tieba_汽車

tieba_飛機

tieba_火箭

tieba_unite

這個表汽車、火箭表是屬於熱門表,定義為新建的版塊放在unite表裡面,待到其超過一萬張主貼的時候才開對應表結構。因為在貼吧這種系統中,冷門版塊

肯定比熱門版塊多得多,這些冷門版塊通常只有幾張帖子,為它們開表也太浪費了;同時熱門版塊數量和訪問量等,又比冷門版塊多得多,非常有特點。

unite表還可以擴充套件成雜湊表,利用詞條的md5編碼,可以分成n張表,我算了一下,md5前一位可分36張表,兩位即是1296張表,足夠了。

tieba_unite_ab

tieba_unite_ac

(3)按雜湊結構

雜湊結構通常用於部落格之類的基於使用者的場合,在部落格這樣的系統裡有幾個特點,1是使用者數量非常多,2是每個使用者發的文章數量都較少,3是使用者發文章不定

期,4是每個使用者發得不多,但總量仍非常之大。基於這些特點,用以上所說的任何一種分表方式都不合適,一沒有固定的時效不宜用時間拆,二使用者很多,而且還

偏偏都是冷門,所以也不宜用版塊(使用者)拆。

雜湊結構在上面有所提及,既然按每個使用者不好直接拆,那就把一群使用者歸進乙個表好了。

blog_aa

blog_ab

blog_ac

如上所說,md5取前兩位雜湊可以達到1296張表,如果覺得不夠,那就再加一位,總數可達46656張表,還不夠?

表的數量太多,要建立這些表也是挺麻煩的,可以考慮在程式裡往資料庫insert之前,多執行一句判斷表存在與否並建立表的語句,很實用,消耗也並不很大。

主鍵:依舊要考慮的,在這個系統中,主鍵是使用者id+時間戳,單純的時間戳或自動編號也能用,但查詢時要記得帶上使用者名稱用於定位表。

mysql分表和表分割槽詳解

為什麼要分表和分割槽?日常開發中我們經常會遇到大表的情況,所謂的大表是指儲存了百萬級乃至千萬級條記錄的表。這樣的表過於龐大,導致資料庫在查詢和插入的時候耗時太長,效能低下,如果涉及聯合查詢的情況,效能會更加糟糕。分表和表分割槽的目的就是減少資料庫的負擔,提高資料庫的效率,通常點來講就是提高表的增刪改...

mysql分表和表分割槽詳解

為什麼要分表和分割槽?日常開發中我們經常會遇到大表的情況,所謂的大表是指儲存了百萬級乃至千萬級條記錄的表。這樣的表過於龐大,導致資料庫在查詢和插入的時候耗時太長,效能低下,如果涉及聯合查詢的情況,效能會更加糟糕。分表和表分割槽的目的就是減少資料庫的負擔,提高資料庫的效率,通常點來講就是提高表的增刪改...

mysql分表和表分割槽詳解

為什麼要分表和分割槽?日常開發中我們經常會遇到大表的情況,所謂的大表是指儲存了百萬級乃至千萬級條記錄的表。這樣的表過於龐大,導致資料庫在查詢和插入的時候耗時太長,效能低下,如果涉及聯合查詢的情況,效能會更加糟糕。分表和表分割槽的目的就是減少資料庫的負擔,提高資料庫的效率,通常點來講就是提高表的增刪改...