MySQL數(shù)據(jù)庫優(yōu)化之分表分庫操作實(shí)例詳解
本文實(shí)例講述了MySQL數(shù)據(jù)庫優(yōu)化之分表分庫操作。分享給大家供大家參考,具體如下:
分表分庫
垂直拆分
垂直拆分就是要把表按模塊劃分到不同數(shù)據(jù)庫表中(當(dāng)然原則還是不破壞第三范式),這種拆分在大型網(wǎng)站的演變過程中是很常見的。當(dāng)一個(gè)網(wǎng)站還在很小的時(shí)候,只有小量的人來開發(fā)和維護(hù),各模塊和表都在一起,當(dāng)網(wǎng)站不斷豐富和壯大的時(shí)候,也會(huì)變成多個(gè)子系統(tǒng)來支撐,這時(shí)就有按模塊和功能把表劃分出來的需求。其實(shí),相對(duì)于垂直切分更進(jìn)一步的是服務(wù)化改造,說得簡(jiǎn)單就是要把原來強(qiáng)耦合的系統(tǒng)拆分成多個(gè)弱耦合的服務(wù),通過服務(wù)間的調(diào)用來滿足業(yè)務(wù)需求看,因此表拆出來后要通過服務(wù)的形式暴露出去,而不是直接調(diào)用不同模塊的表,淘寶在架構(gòu)不斷演變過程,最重要的一環(huán)就是服務(wù)化改造,把用戶、交易、店鋪、寶貝這些核心的概念抽取成獨(dú)立的服務(wù),也非常有利于進(jìn)行局部的優(yōu)化和治理,保障核心模塊的穩(wěn)定性
垂直拆分用于分布式場(chǎng)景。
水平拆分
上面談到垂直切分只是把表按模塊劃分到不同數(shù)據(jù)庫,但沒有解決單表大數(shù)據(jù)量的問題,而水平切分就是要把一個(gè)表按照某種規(guī)則把數(shù)據(jù)劃分到不同表或數(shù)據(jù)庫里。例如像計(jì)費(fèi)系統(tǒng),通過按時(shí)間來劃分表就比較合適,因?yàn)橄到y(tǒng)都是處理某一時(shí)間段的數(shù)據(jù)。而像SaaS應(yīng)用,通過按用戶維度來劃分?jǐn)?shù)據(jù)比較合適,因?yàn)橛脩襞c用戶之間的隔離的,一般不存在處理多個(gè)用戶數(shù)據(jù)的情況,簡(jiǎn)單的按user_id范圍來水平切分
通俗理解:水平拆分行,行數(shù)據(jù)拆分到不同表中, 垂直拆分列,表數(shù)據(jù)拆分到不同表中
水平分割案例
思路:在大型電商系統(tǒng)中,每天的會(huì)員人數(shù)不斷的增加。達(dá)到一定瓶頸后如何優(yōu)化查詢。
可能大家會(huì)想到索引,萬一用戶量達(dá)到上億級(jí)別,如何進(jìn)行優(yōu)化呢?
使用水平分割拆分?jǐn)?shù)據(jù)庫表。
如何使用水平拆分?jǐn)?shù)據(jù)庫
使用水平分割拆分表,具體根據(jù)業(yè)務(wù)需求,有的按照注冊(cè)時(shí)間、取摸、賬號(hào)規(guī)則、年份等。
使用取摸方式分表
首先我創(chuàng)建三張表 user0 / user1 /user2 , 然后我再創(chuàng)建 uuid表,該表的作用就是提供自增的id。
create table user0( id int unsigned primary key , name varchar(32) not null default '', pwd varchar(32) not null default '') engine=myisam charset utf8; create table user1( id int unsigned primary key , name varchar(32) not null default '', pwd varchar(32) not null default '') engine=myisam charset utf8; create table user2( id int unsigned primary key , name varchar(32) not null default '', pwd varchar(32) not null default '') engine=myisam charset utf8; create table uuid( id int unsigned primary key auto_increment)engine=myisam charset utf8;
創(chuàng)建一個(gè)demo項(xiàng)目
POM文件
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.3.3.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
Service代碼
@Service
public class UserService {
@Autowired
private JdbcTemplate jdbcTemplate;
public String regit(String name, String pwd) {
// 1.先獲取到 自定增長(zhǎng)ID
String idInsertSQL = "INSERT INTO uuid VALUES (NULL);";
jdbcTemplate.update(idInsertSQL);
Long insertId = jdbcTemplate.queryForObject("select last_insert_id()", Long.class);
// 2.判斷存儲(chǔ)表名稱
String tableName = "user" + insertId % 3;
// 3.注冊(cè)數(shù)據(jù)
String insertUserSql = "INSERT INTO " + tableName + " VALUES ('" + insertId + "','" + name + "','" + pwd
+ "');";
System.out.println("insertUserSql:" + insertUserSql);
jdbcTemplate.update(insertUserSql);
return "success";
}
public String get(Long id) {
String tableName = "user" + id % 3;
String sql = "select name from " + tableName + " where id="+id;
System.out.println("SQL:" + sql);
String name = jdbcTemplate.queryForObject(sql, String.class);
return name;
}
}
Controller
@RestController
public class UserController {
@Autowired
private UserService userService;
@RequestMapping("/regit")
public String regit(String name, String pwd) {
return userService.regit(name, pwd);
}
@RequestMapping("/get")
public String get(Long id) {
String name = userService.get(id);
return name;
}
}
更多關(guān)于MySQL相關(guān)內(nèi)容感興趣的讀者可查看本站專題:《MySQL查詢技巧大全》、《MySQL常用函數(shù)大匯總》、《MySQL日志操作技巧大全》、《MySQL事務(wù)操作技巧匯總》、《MySQL存儲(chǔ)過程技巧大全》及《MySQL數(shù)據(jù)庫鎖相關(guān)技巧匯總》
希望本文所述對(duì)大家MySQL數(shù)據(jù)庫計(jì)有所幫助。
相關(guān)文章
MySQL優(yōu)化教程之慢查詢?nèi)罩緦?shí)踐
在MySQL中慢查詢?nèi)罩局饕脕碛涗涰憫?yīng)時(shí)間超過閾值的SQL,下面這篇文章主要給大家介紹了關(guān)于MySQL優(yōu)化教程之慢查詢?nèi)罩镜南嚓P(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-06-06
MySQL 編碼utf8 與 utf8mb4 utf8mb4_unicode_ci 與 utf8mb4_general_
這篇文章主要介紹了MySQL 編碼utf8 與 utf8mb4 utf8mb4_unicode_ci 與 utf8mb4_general_ci的相關(guān)知識(shí),本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-05-05
Navicat 連接MySQL8.0.11出現(xiàn)2059錯(cuò)誤
這篇文章主要介紹了Navicat 連接MySQL8.0.11出現(xiàn)2059錯(cuò)誤,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-11-11
MySQL報(bào)錯(cuò) table “xxx” doesn‘t exit的解決
本文主要介紹了MySQL報(bào)錯(cuò) table “xxx” doesn‘t exit的解決,主要原因是英文字母大小寫敏感導(dǎo)致,下面就來介紹一下解決方法,感興趣的可以了解一下2023-10-10
安裝配置MySQLMTOP來監(jiān)控MySQL運(yùn)行性能的教程
這篇文章主要介紹了安裝配置MySQLMTOP來監(jiān)控MySQL運(yùn)行性能的教程,MySQLMTOP具有B/S方式的圖形化操作頁面,需要的朋友可以參考下2015-12-12

