SpringBoot+MybatisPlus+Mysql+Sharding-JDBC分庫分表實踐

一蕾殴、序言

在實際業(yè)務中,單表數(shù)據(jù)增長較快黄伊,很容易達到數(shù)據(jù)瓶頸泪酱,比如單表百萬級別數(shù)據(jù)量。當數(shù)據(jù)量繼續(xù)增長時还最,數(shù)據(jù)的查詢性能即使有索引的幫助下也不盡如意墓阀,這時可以引入數(shù)據(jù)分庫分表技術(shù)。

本文將基于SpringBoot+MybatisPlus+Sharding-JDBC+Mysql實現(xiàn)企業(yè)級分庫分表憋活。

1岂津、組件及版本選擇
SpringBoot
MybatisPlus
Sharding-JDBC
Mysql
SpringBoot 2.6.x MybatisPlus 3.5.0 Sharding-JDBC 4.1.1 Mysql 5.7.35
2虱黄、預期目標
  • 使用上述組件實現(xiàn)分庫分表悦即,簡化起見只討論分表技術(shù)
  • 完成分表后的邏輯表與物理表間的增刪查改
  • 引入邏輯刪除和使用MybatisPlus內(nèi)置分頁技術(shù)

完整項目源碼訪問地址

二橱乱、代碼實現(xiàn)

為了簡化分表復雜性辜梳,專注于分表整體實現(xiàn),簡化分表邏輯:按照UserId的奇偶屬性分別進行分表泳叠。以訂單表這一典型場景為例作瞄,一般來說有關(guān)訂單表,通常具有如下共性行為:

  • 創(chuàng)建訂單記錄
  • 查詢XX用戶的訂單列表
  • 查詢XX用戶的訂單列表(分頁)
  • 查詢XX訂單詳情
  • 修改訂單狀態(tài)
  • 刪除訂單(邏輯刪除)

接下來通過代碼實現(xiàn)上述目標危纫。

(一)素材準備

1宗挥、實體類
@Data
@TableName("bu_order")
public class Order {
    @TableId
    private Long orderId;
    private Integer orderType;
    private Long userId;
    private Double amount;
    private Integer orderStatus;
    @TableLogic
    @JsonIgnore
    private Boolean deleted;
}
2、Mapper類
@Mapper
public interface OrderMapper extends BaseMapper<Order> {
}
3种蝶、全局配置文件
spring:
  config:
    use-legacy-processing: true
  shardingsphere:
    datasource:
      ds1:
        driver-class-name: com.Mysql.cj.jdbc.Driver
        type: com.alibaba.druid.pool.DruidDataSource
        url: jdbc:mysql://127.0.0.1:3306/sharding-jdbc2?serverTimezone=UTC
        username: root
        password: 123456
      names: ds1
    props:
      SQL:
        show: true
    sharding:
      tables:
        bu_order:
          actual-data-nodes: ds1.bu_order_$->{0..1}
          key-generator:
            column: order_id
            type: SNOWFLAKE
          table-strategy:
            inline:
              algorithm-expression: bu_order_${user_id%2}
              sharding-column: user_id

(二)增刪查改

1契耿、保存數(shù)據(jù)

由于依據(jù)主鍵的奇偶屬性對原表分表,分表后每張表的數(shù)據(jù)量是分表前的二分之一螃征。根據(jù)需要也可以自定義分表數(shù)量(比如10張)搪桂,新分表后的數(shù)據(jù)量是不分表前的十分之一。

@Test
public void addOrders() {
    for (long i = 1; i <= 10; i++) {
        Order order = new Order();
        order.setOrderId(i);
        order.setOrderType(RandomUtil.randomEle(Arrays.asList(1, 2)));
        order.setUserId(RandomUtil.randomEle(Arrays.asList(101L, 102L, 103L)));
        order.setAmount(1000.0 * i);
        orderMapper.insert(order);
    }
}
2盯滚、查詢列表數(shù)據(jù)

查詢指定用戶的訂單列表踢械。

@GetMapping("/list")
public AjaxResult list(Order order) {
    LambdaQueryWrapper<Order> wrapper = Wrappers.lambdaQuery(order);
    return AjaxResult.success(orderMapper.selectList(wrapper));
}
3酗电、分頁查詢數(shù)據(jù)

分頁查詢指定用戶的訂單列表

@GetMapping("/page")
public AjaxResult page(Page<Order> page, Order order) {
    return AjaxResult.success(orderMapper.selectPage(page, Wrappers.lambdaQuery(order)));
}
4、查詢詳情

通過訂單ID查詢訂單詳情内列。

@GetMapping("/detail/{orderId}")
public AjaxResult detail(@PathVariable Long orderId) {
    return AjaxResult.success(orderMapper.selectById(orderId));
}
5撵术、刪除數(shù)據(jù)

通過訂單ID刪除訂單(邏輯刪除)

@DeleteMapping("/delete/{orderId}")
public AjaxResult delete(@PathVariable Long orderId) {
    return AjaxResult.success(orderMapper.deleteById(orderId));
}
6、修改數(shù)據(jù)

修改數(shù)據(jù)一般涉及部分列德绿,比如修改訂單表的訂單狀態(tài)等荷荤。

@PutMapping("/edit")
public AjaxResult edit(@RequestBody Order order) {
    return AjaxResult.success(orderMapper.updateById(order));
}

三、理論分析

1移稳、選擇分片列

選擇分片列是經(jīng)過精心對比后確定的蕴纳,對于訂單類場景,需要頻繁以用戶ID為查詢條件篩選數(shù)據(jù)个粱,因此將同一個用戶的訂單數(shù)據(jù)存放在一起有利于提高查詢效率古毛。

2、擴容

當分表后的表數(shù)據(jù)快速增長都许,可以預見即將達到瓶頸時稻薇,需要對分表進行擴容,擴容以2倍的速率進行胶征,擴容期間需要遷移數(shù)據(jù)塞椎,工作量相對可控。


喜歡本文點個??贊??支持一下睛低,如有需要案狠,可通過微信dream4s與我聯(lián)系。相關(guān)源碼在GitHub钱雷,視頻講解在B站骂铁,本文收藏在博客天地


最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末罩抗,一起剝皮案震驚了整個濱河市拉庵,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌套蒂,老刑警劉巖钞支,帶你破解...
    沈念sama閱讀 210,978評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異操刀,居然都是意外死亡烁挟,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,954評論 2 384
  • 文/潘曉璐 我一進店門馍刮,熙熙樓的掌柜王于貴愁眉苦臉地迎上來信夫,“玉大人,你說我怎么就攤上這事【驳荆” “怎么了警没?”我有些...
    開封第一講書人閱讀 156,623評論 0 345
  • 文/不壞的土叔 我叫張陵,是天一觀的道長振湾。 經(jīng)常有香客問我杀迹,道長,這世上最難降的妖魔是什么押搪? 我笑而不...
    開封第一講書人閱讀 56,324評論 1 282
  • 正文 為了忘掉前任树酪,我火速辦了婚禮,結(jié)果婚禮上大州,老公的妹妹穿的比我還像新娘续语。我一直安慰自己,他們只是感情好厦画,可當我...
    茶點故事閱讀 65,390評論 5 384
  • 文/花漫 我一把揭開白布疮茄。 她就那樣靜靜地躺著,像睡著了一般根暑。 火紅的嫁衣襯著肌膚如雪力试。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,741評論 1 289
  • 那天排嫌,我揣著相機與錄音畸裳,去河邊找鬼。 笑死淳地,一個胖子當著我的面吹牛怖糊,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播薇芝,決...
    沈念sama閱讀 38,892評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼蓬抄,長吁一口氣:“原來是場噩夢啊……” “哼丰嘉!你這毒婦竟也來了夯到?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,655評論 0 266
  • 序言:老撾萬榮一對情侶失蹤饮亏,失蹤者是張志新(化名)和其女友劉穎耍贾,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體路幸,經(jīng)...
    沈念sama閱讀 44,104評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡荐开,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,451評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了简肴。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片晃听。...
    茶點故事閱讀 38,569評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出能扒,到底是詐尸還是另有隱情佣渴,我是刑警寧澤,帶...
    沈念sama閱讀 34,254評論 4 328
  • 正文 年R本政府宣布初斑,位于F島的核電站辛润,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏见秤。R本人自食惡果不足惜砂竖,卻給世界環(huán)境...
    茶點故事閱讀 39,834評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望鹃答。 院中可真熱鬧乎澄,春花似錦、人聲如沸测摔。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,725評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽避咆。三九已至舟肉,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間查库,已是汗流浹背路媚。 一陣腳步聲響...
    開封第一講書人閱讀 31,950評論 1 264
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留樊销,地道東北人整慎。 一個月前我還...
    沈念sama閱讀 46,260評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像围苫,于是被迫代替她去往敵國和親裤园。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,446評論 2 348

推薦閱讀更多精彩內(nèi)容