1.爲何要分表和分區?
平常開發中咱們常常會遇到大表的狀況,所謂的大表是指存儲了百萬級乃至千萬級條記錄的表。這樣的表過於龐大,致使數據庫在查詢和插入的時候耗時太長,性能低下,若是涉及聯合查詢的狀況,性能會更加糟糕。分表和表分區的目的就是減小數據庫的負擔,提升數據庫的效率,一般點來說就是提升表的增刪改查效率。
2.什麼是分表?
分表是將一個大表按照必定的規則分解成多張具備獨立存儲空間的實體表,咱們能夠稱爲子表,每一個表都對應三個文件,MYD數據文件,.MYI索引文件,.frm表結構文件。這些子表能夠分佈在同一塊磁盤上,也能夠在不一樣的機器上。app讀寫的時候根據事先定義好的規則獲得對應的子表名,而後去操做它。
3.什麼是分區?
分區和分表類似,都是按照規則分解表。不一樣在於分表將大表分解爲若干個獨立的實體表,而分區是將數據分段劃分在多個位置存放,能夠是同一塊磁盤也能夠在不一樣的機器。分區後,表面上仍是一張表,但數據散列到多個位置了。app讀寫的時候操做的仍是大表名字,db自動去組織分區的數據。
4.mysql分表和分區有什麼聯繫呢?
(1)都能提升mysql的性高,在高併發狀態下都有一個良好的表現。
(2)分表和分區不矛盾,能夠相互配合的,對於那些大訪問量,而且表數據比較多的表,咱們能夠採起分表和分區結合的方式(若是merge這種分表方式,不能和分區配合的話,能夠用其餘的分表試),訪問量不大,可是表數據不少的表,咱們能夠採起分區的方式等。
(3)分表技術是比較麻煩的,須要手動去建立子表,app服務端讀寫時候須要計算子表名。採用merge好一些,但也要建立子表和配置子表間的union關係。
(4)表分區相對於分表,操做方便,不須要建立子表。html
1.分區的類型:
(1)Range:把連續區間按範圍劃分
例:mysql
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:把離散值分紅集合,按集合劃分,適合有固定取值列的表
例:web
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:隨機分配,分區數固定
例:sql
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)刪除分區app
--當刪除了一個分區,也同時刪除了該分區中全部的數據。 ALTER TABLE sale_data DROP PARTITION p201710;
(3)分區的合併
下面的SQL,將p201701 - p201709 合併爲3個分區p2017Q1 - p2017Q3less
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
可看到每個版塊都對應着一組相同的表結構,好處就是一目瞭然。在功能上,由於版塊之間仍是有一些隔閡,因此須要聯合查詢的需求很少,開發上比時間結構的方式要輕鬆。
主鍵:依舊要考慮的,在這個系統中,主鍵是版塊+時間戳,單純的時間戳或自動編號也能用,查詢時要記得帶上版塊用於定位表。
(b)冷熱式
對應式的缺點是,若是版塊數量很大並且不肯定,那要分出的表數量就太多了。舉個例子:百度貼吧,若是按一個詞條一個表設計,那得有多少張表呢?
用這樣的方式吧。
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鎖詳解
MySQL事務
MySQL索引類型
參考資料:
http://blog.csdn.net/shmnh/article/details/44055059
http://blog.csdn.net/hijiankang/article/details/9173825
http://blog.csdn.net/feihong247/article/details/8100960
http://niehan.blog.techweb.com.cn/archives/279.html