如下內容皆爲我的摸索,沒有人專門指導(公司不給力啊!DBA和大牛都木有。。。),因此不免出錯,若有錯誤歡迎指正,小子敢於接受批評~(*^__^*) ~github
水平分庫分表和垂直分庫分表,你們都常常談,我說下個人理解,看圖:算法
垂直分表就不用說了,基本上會SQLServer的都會。sql
垂直分庫就是根據業務需求來分庫,好比教育系列的,能夠分爲資訊,課程,用戶(學生,學校)三個數據庫。好比電商的能夠分爲訂單,商品,用戶(商家,消費者)三個數據庫。這邊只是舉個例子,具體的你得根據大家本身業務的實際狀況來分,不是分的越多越好,最好是遇到瓶頸了再去作這些事情(這個過程才能學到不少東西)數據庫
水平分表主要就兩種方法,Hash取餘法和時間路由法。我重點說下時間路由的方法,這種方案後期擴容和歷史數據抽離【結合列索引更勁爆哦~】比較方便。安全
舉個簡單的路由表:(時間你能夠用傳統的格式,我這邊用的是時間軸)性能優化
這個是文章表的時間路由表,每次查詢文章的時候根據查詢的時間看看服務器
好比我如今準備寫入數據,當前時間 2016/11/18 16:37:29 ==》1479458249多線程
select RTableName from Route_Article where where 1479458249 between RCreateTime and REndTime
就能夠知道我應該往哪一個表裏面寫數據:==》Article2
同理,想查詢某個時間的數據也是能夠經過路由表知道該往哪一個表裏面查詢
水平分庫以前提了一下文件組(http://www.cnblogs.com/dunitian/p/5276431.html)後面還會有一篇文章進行擴展說明(http://www.cnblogs.com/dunitian/p/6078512.html),這邊就不說了。
其實企業裏面用的最多的是複合型的,好比:水平分庫分表 ,水平分庫+垂直分庫+分表
真的有了這方面的瓶頸的話水平分表通常只能緩解,並不能真正解決,畢竟仍是在一臺服務器上。單表的數據量是減小了,可是IO,鏈接數,帶寬之類的瓶頸並不能有多大的改善。
水平分庫分表能夠把IO瓶頸解決一部分,優化效果仍是很明顯的:
水平分庫+垂直分庫+分表,這個方案能夠利用連接服務器,這樣路由表就不用改了,把路由表的表名改爲完整的名稱(後面會說更好的方法)
看直觀圖:[192.168.1.250].[BigValues].[dbo].[Article]
我簡單模擬一下:我PC的IP是:192.168.1.9
先在遠程數據庫稍微插點數據:2013-1-1 ~ 2015-1-1的數據,量卻是很少,200W左右
沒有跨庫查詢過的同志,能夠先預習一下同義詞相關的知識:http://www.cnblogs.com/dunitian/p/6041323.html#tyc
先設置一下連接服務器。我本身摸索的這個方法可能和網上的不太同樣,不要慌(沒辦法,我按照網上的沒成功啊+_+)
安全性裏面設置一下用戶名和密碼
能夠了,看看吧:
先看看效果:
這個感受挺好的,通常狀況下都是沒問題的,可是遇到數據庫名字或者表改了就蛋疼了,得改多少東西??關鍵是不太方便,名字那麼長。。。===》so,引入了同義詞
create synonym Article for [192.168.1.250].[BigValues].[dbo].[Article]
再看看效果吧:
-----------------------------------------------------------------------------------------------------
是否是感受特簡單,也想改革起來了?(⊙o⊙)…,其實我仍是建議快到瓶頸的時候再改,否則你會很蛋疼的,如今我就簡單說幾個蛋疼的地方~PS:附帶個人解決方案
簡單說下有哪些問題:
1.全局ID的問題,既然分表了,那麼第一件事情就是把自增加去掉,(eg:表A,ID爲44,表B,ID爲44,那我取44的數據時,取哪一個呢?)
一開始我是用GUID的方式,一直認爲這個不太好,爲啥呢,我通常用戶ID或者管理員ID會用GUID,這樣Burp的暴力解猜就比較上門檻了(簡單使用:http://www.cnblogs.com/dunitian/p/5724872.html)
後來發現,GUID的主鍵基本上知足需求,可是無序列,並且太長了,排序什麼的都各類不方便,後來就找其餘方法,不少,好比時間軸,後來發現高併發下仍是有重複的(畢竟已經不是單機了)最終採起了雪花算法(https://github.com/twitter/snowflake)
C#版本的國外朋友已經封裝了,你們能夠去看看:https://github.com/ccollie/snowflake-net
強大的網友出來個簡化版本:http://blog.csdn.net/***/article/details/***6 (地址我就不貼了,對前輩須要最起碼的尊敬)
一開始我用的是這個版本,後來發現多線程的狀況下有重複項。。。(demo:https://github.com/dunitian/TempCode/tree/master/2016-11-16/Twitter_Snowflake)
全局ID的激烈討論:https://q.cnblogs.com/q/53552/
具體實現:http://www.cnblogs.com/dunitian/p/6130543.html
2.跨庫Join
MySQL比較蛋疼,MSSQL好像沒那麼難,我是用連接服務器+同義詞的方法解決的(上面演示的),若是有更好方案能夠提點一下小子^_^
看圖:
不少時候能夠參考MyCat的一些東西,跨庫查詢確定效率沒有單機高。有時候會作一些處理來儘可能避免跨庫Join
好比說表A,表B,表C...經常使用的全局表我會把他們每一個數據庫存一遍,這樣就方便多了(注意一下數據同步哦)
還有就是冗餘一些字段
好比:產品表有這些字段:商品展圖ID,展圖URL,縮略展圖URL。按理說這是不合理的,可是不這麼幹就得跨庫查詢了,適當犧牲嘛~
再好比:訂單表裏面:用戶ID,用戶名,店鋪ID,店鋪名,商品縮略展圖。這樣也是不合理的,可是。。。商品和訂單你們都懂的,牽扯的表太多,有點誇張了~
之後分庫的時候能夠參考MyCat的ER分庫 (相關聯的一塊兒分)
3.跨庫排序、聚合等
好比要求Count,那麼每一個表都得單獨求一下Count,而後彙總Count。這個過程能夠經過應用程序去完成,畢竟能夠根據路由表來統一彙總
排序就比較蛋疼了,若是是按時間(分表字段)的還好,由於咱們路由表就是按時間分表的,相對簡單。若是按照某個字段排序的話。。。。。(⊙o⊙)…沒辦法就取每一個表裏面的數據吧。
不少人老是疑惑爲何分頁越日後面越慢(按時間不怕,咱們就是按時間分表的,你去對應時間區裏面取就行了)
好比按字段1排序,每一頁20條數據,要求取第一頁的數據==》
取第五頁的數據==》想一想看,這麼搞的話,怎麼不卡?大家有更好的解決方法能夠說,小子比較菜O(∩_∩)O
(⊙o⊙)…,最後說下我最近在研究的解決方案:
分佈式數據庫訪問層:攜程DAL ,支持MySQL,SQLServer。支持Net,Java
Ctrip DAL支持流行的分庫分表操做,支持Java和C#,支持Mysql和MSSqlServer。使用該框架能夠在有效地保護企業已有數據庫投資的同時,迅速,可靠地爲企業提供數據庫訪問層的橫向擴展能力。
開源地址:https://github.com/ctripcorp/dal
文檔系列:https://github.com/ctripcorp/dal/wiki/
這個是後備方案:(下午讓朋友去問了一些MyCat的做者,他說MyCat開發的時候就沒有限定數據庫和開發語言,MySQL,SQLServer都是支持的,換個端口而已,開發語言也沒什麼限制,只要你能鏈接MyCat就能用)
數據庫中間組件:MyCat (我還沒研究,改天要是能夠就發篇文章)
文檔:https://github.com/MyCATApache/Mycat-doc
開源地址:https://github.com/MyCATApache/Mycat-Server
04.SQLServer性能優化之---讀寫分離&數據同步 http://www.cnblogs.com/dunitian/p/6041758.html