mysql分庫分表一般有如下場景
成都創(chuàng)新互聯(lián)從2013年開始,是專業(yè)互聯(lián)網(wǎng)技術服務公司,擁有項目網(wǎng)站制作、網(wǎng)站建設網(wǎng)站策劃,項目實施與項目整合能力。我們以讓每一個夢想脫穎而出為使命,1280元順昌做網(wǎng)站,已為上家服務,為順昌各地企業(yè)和個人服務,聯(lián)系電話:18980820575
其中1,2相對較容易實現(xiàn),本文重點講講水平拆表和水平拆庫,以及基于mybatis插件方式實現(xiàn)水平拆分方案落地。
在 《聊一聊擴展字段設計》 一文中有講解到基于KV水平存儲擴展字段方案,這就是非常典型的可以水平分表的場景。主表和kv表是一對N關系,隨著主表數(shù)據(jù)量增長,KV表最大N倍線性增長。
這里我們以分KV表水平拆分為場景
對于kv擴展字段查詢,只會根據(jù)id + key 或者 id 為條件的方式查詢,所以這里我們可以按照id 分片即可
分512張表(實際場景具體分多少表還得根據(jù)字段增加的頻次而定)
分表后表名為kv_000 ~ kv_511
id % 512 = 1 .... 分到 kv_001,
id % 512 = 2 .... 分到 kv_002
依次類推!
水平分表相對比較容易,后面會講到基于mybatis插件實現(xiàn)方案
場景:以下我們基于博客文章表分庫場景來分析
目標:
表結構如下(節(jié)選部分字段):
按照user_id sharding
假如分1024個庫,按照user_id % 1024 hash
user_id % 1024 = 1 分到db_001庫
user_id % 1024 = 2 分到db_002庫
依次類推
目前是2個節(jié)點,假如后期達到瓶頸,我們可以增加至4個節(jié)點
最多可以增加只1024個節(jié)點,性能線性增長
對于水平分表/分庫后,非shardingKey查詢首先得考慮到
基于mybatis分庫分表,一般常用的一種是基于spring AOP方式, 另外一種基于mybatis插件。其實兩種方式思路差不多。
為了比較直觀解決這個問題,我分別在Executor 和StatementHandler階段2個攔截器
實現(xiàn)動態(tài)數(shù)據(jù)源獲取接口
測試結果如下
由此可知,我們需要在Executor階段 切換數(shù)據(jù)源
對于分庫:
原始sql:
目標sql:
其中定義了三個注解
@useMaster 是否強制讀主
@shardingBy 分片標識
@DB 定義邏輯表名 庫名以及分片策略
1)編寫entity
Insert
select
以上順利實現(xiàn)mysql分庫,同樣的道理實現(xiàn)同時分庫分表也很容易實現(xiàn)。
此插件具體實現(xiàn)方案已開源:
目錄如下:
mysql分庫分表,首先得找到瓶頸在哪里(IO or CPU),是分庫還是分表,分多少?不能為了分庫分表而拆分。
原則上是盡量先垂直拆分 后 水平拆分。
以上基于mybatis插件分庫分表是一種實現(xiàn)思路,還有很多不完善的地方,
例如:
mysql表很大sum不全的解決辦法:
1、優(yōu)化sql和索引。
2、加緩存,memcached,redis。
3、以上都做了后,還是慢,就做主從復制或主主復制,讀寫分離,可以在應用層做,效率高,也可以用三方工具,第三方工具推薦360的atlas,其它的要么效率不高,要么沒人維護。
4、以上都做了還是慢,不要想著去做切分,mysql自帶分區(qū)表,先試試這個,對應用是透明的,無需更改代碼,sql語句是需要針對分區(qū)表做優(yōu)化的,sql條件中要帶上分區(qū)條件的列,從而使查詢定位到少量的分區(qū)上,否則就會掃描全部分區(qū)。
5、以上都做了,那就先做垂直拆分,其實就是根據(jù)模塊的耦合度,將一個大的系統(tǒng)分為多個小的系統(tǒng),也就是分布式系統(tǒng)。
6、水平切分,針對數(shù)據(jù)量大的表,這一步最麻煩,最能考驗技術水平,要選擇一個合理的shardingkey,為了有好的查詢效率,表結構也要改動,做一定的冗余,應用也要改,sql中盡量帶shardingkey,將數(shù)據(jù)定位到限定的表上去查,而不是掃描全部的表。
一、優(yōu)化表的數(shù)據(jù)類型
select * from tablename procedure analyse(16.265);
上面輸出一列信息,牟你數(shù)據(jù)表的字段提出優(yōu)化建義,
二、通過拆分表提高數(shù)據(jù)訪問效率
拆分一是指針對表進行拆分,如果是針對myisam類型的表進行處理的話,可以有兩種拆分方法
1、是垂直拆分,把主要的與一些散放到一個表,然后把主要的和另外的列放在另一張表。
2、水平拆分方法,根據(jù)一列或多列的值把數(shù)據(jù)行放到兩個獨立的表中,水平拆分通常幾種情況。
表很大,拆分后可降低查詢時數(shù)據(jù)和索引的查詢速度,同時也降低了索引的層數(shù),提高查詢的速度。
表中的數(shù)據(jù)本來就有獨立性,表中分別記錄各個地區(qū)的數(shù)據(jù)或不同時期的數(shù)據(jù),特別是有些數(shù)據(jù)常用,廁國一些數(shù)據(jù)不常用的情況下,
需要把數(shù)據(jù)存放到多個不同的介質(zhì)上。
三、逆規(guī)范化
四、使用中間表優(yōu)化方法
對于數(shù)據(jù)庫教程大的表源碼天空
mysql數(shù)據(jù)庫最適合中型規(guī)模的項目。盡量不要垂直分表。單純的垂直分表對性能提升沒什么幫助。
優(yōu)化方案:
主從同步+讀寫分離:
這個表在有設備條件的情況下,讀寫分離,這樣能減少很多壓力,而且數(shù)據(jù)穩(wěn)定性也能提高
縱向分表:
根據(jù)原則,每個表最多不要超過5個索引,縱向拆分字段,將部分字段拆到一個新表
通常我們按以下原則進行垂直拆分:(先區(qū)分這個表中的冷熱數(shù)據(jù)字段)
把不常用的字段單獨放在一張表;
把text,blob等大字段拆分出來放在附表中;
經(jīng)常組合查詢的列放在一張表中;
缺點是:很多邏輯需要重寫,帶來很大的工作量。
利用表分區(qū):
這個是推薦的一個解決方案,不會帶來重寫邏輯等,可以根據(jù)時間來進行表分區(qū),相當于在同一個磁盤上,表的數(shù)據(jù)存在不同的文件夾內(nèi),能夠極大的提高查詢速度。
橫向分表:
1000W條數(shù)據(jù)不少的,會帶來一些運維壓力,備份的時候,單表備份所需時間會很長,所以可以根據(jù)服務器硬件條件進行水平分表,每個表有多少數(shù)據(jù)為準。