說過不少次,不要拘泥於某一個技術的一點,技術是相通的。重要的是編程思想,思想是最重要的。當數據量大的時候,須要具備分的思想去細化粒度。當數據量太碎片的時候,須要具備合的思想來粗化粒度。html
不少技術都運用了分的編程思想,這裏來舉幾個例子,這些都是分的思想mysql
不少技術也運用到了合的編程思想,這裏舉幾個例子,這些都是合的思想算法
本文一切基於MySql InnoDBsql
說了這麼多,接下來講主體,先說分區,由於以前博主寫過一篇MySql分區的博客因此這裏不會多費筆墨來寫,具體見:http://www.javashuo.com/article/p-myhkzsfl-ho.html數據庫
具體如何實現上面連接裏有寫,這裏只需記住若是表中存在主鍵或惟一索引時,分區列必須是惟一索引的一個組成部分。編程
這個是數據庫分的,應用透明,代碼無需修改任何東西。緩存
先去data目錄,若是不知道目錄位置的能夠執行:安全
接下來看下內部文件:網絡
從上圖咱們能夠看出,有2中類型的文件,.frm文件和.ibd文件多線程
分區表後,提升了MySql性能。若是一張表的話,那就只有一個.ibd文件,一顆大的B+樹。若是分表後,將按分區規則,分紅不一樣的區,也就是一個大的B+樹,分紅多個小的樹。
(PS:若是想研究一顆彙集索引B+樹能夠放多少行數據,請看:http://www.javashuo.com/article/p-cktkdfzo-bh.html)
讀的效率確定提高了,若是走分區鍵索引的話,先走對應分區的輔助索引B+樹,再走對應分區的彙集索引B+樹。
若是沒有走分區鍵,將會在全部分區都會執行一次。會形成屢次邏輯IO!平時開發若是想查看sql語句的分區查詢可使用explain partitons select xxxxx語句。能夠看到一句select語句走了幾個分區。
mysql> explain partitions select * from TxnList where startTime>'2016-08-25 00:00:00' and startTime<'2016-08-25 23:59:00'; +----+-------------+-------------------+------------+------+---------------+------+---------+------+-------+-------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+-------------------+------------+------+---------------+------+---------+------+-------+-------------+ | 1 | SIMPLE | ClientActionTrack | p20160825 | ALL | NULL | NULL | NULL | NULL | 33868 | Using where | +----+-------------+-------------------+------------+------+---------------+------+---------+------+-------+-------------+ row in set (0.00 sec)
當一張表隨着時間和業務的發展,庫裏表的數據量會愈來愈大。數據操做也隨之會愈來愈大。一臺物理機的資源有限,最終能承載的數據量、數據的處理能力都會受到限制。這時候就會使用分庫分表來承接超大規模的表,單機放不下的那種。
區別於分區的是,分區通常都是放在單機裏的,用的比較多的是時間範圍分區,方便歸檔。只不過度庫分表須要代碼實現,分區則是mysql內部實現。分庫分表和分區並不衝突,能夠結合使用。
分庫分表字段取值很是重要
通常使用userId,能夠知足上述條件
分佈式數據庫中間件分爲兩種,proxy和客戶端式架構。proxy模式有MyCat、DBProxy等,客戶端式架構有TDDL、Sharding-JDBC等。那麼proxy和客戶端式架構有何區別呢?各自有什麼優缺點呢?其實看一張圖即可知曉。
proxy模式的話咱們的select和update語句都是發送給代理,由這個代理來操做具體的底層數據庫。因此必需要求代理自己須要保證高可用,不然數據庫沒有宕機,proxy掛了,那就走遠了。
客戶端模式一般在鏈接池上作了一層封裝,內部與不一樣的庫鏈接,sql交給smart-client進行處理。一般僅支持一種語言,若是其餘語言要使用,須要開發多語言客戶端。
各自的優缺點以下:
找了一個分庫分表+分區的例子,基本上和分區表的差很少,只是多了多了不少表的.ibd文件,上面有文件的解釋:
[miaojiaxing@Grim testmydata]# ls | grep 'base_info' base_info_00.frm base_info_00#P#p_2018.ibd base_info_00#P#p_2019.ibd base_info_00#P#p_2020.ibd base_info_00#P#p_2021.ibd base_info_00#P#p_init.ibd base_info_00#P#p_max.ibd base_info_01.frm base_info_01#P#p_2018.ibd base_info_01#P#p_2019.ibd base_info_01#P#p_2020.ibd base_info_01#P#p_2021.ibd base_info_01#P#p_init.ibd base_info_01#P#p_max.ibd base_info.frm base_info.ibd
既然分庫分表了,那麼確定涉及到分佈式事務,如何保證插入到不一樣庫的多條記錄可以要麼同時成功,要麼同時失敗。有些同窗可能想到XA,XA性能差並且不須要使用mysql5.7。柔性事務是目前主流的方案,TCC模式就屬於柔性事務。
對於分佈式事務問題每家公司有本身的實現,華爲用saga,阿里用TXC,螞蟻用DTX,支持FMT模式和TCC模式。
tddl、MyCAT等都支持跨分片join。可是盡力避免跨庫join,好比經過字段冗餘的方式等。
若是出現了這種狀況且中間件支持分片join,那麼能夠這樣使用。若是不支持能夠手工查詢。
分表和在用途上不同,分表是爲了承接超大規模的表,單機放不下那種。分區的話則通常都是放在單機裏的,用的比較多的是時間範圍分區,方便歸檔。性能穩定上的話都是一個個子表,差很少,區別應該是分區表是mysql內部實現的,會比分表方案少一點數據交互