數(shù)據(jù)庫分庫分表最詳解
分庫分表
分庫分表是一種數(shù)據(jù)庫水平擴(kuò)展的方式,用于解決單一數(shù)據(jù)庫的性能瓶頸和容量限制。
圖片
分庫:將一個(gè)邏輯數(shù)據(jù)庫劃分為多個(gè)物理數(shù)據(jù)庫,每個(gè)數(shù)據(jù)庫中存儲部分?jǐn)?shù)據(jù)。
分表:將一個(gè)表拆分為多個(gè)表,每個(gè)表中存儲部分?jǐn)?shù)據(jù)。
分庫分表策略
常見的分庫策略有按:范圍、按哈希和按列表分片。
圖片
1.按范圍分片
根據(jù)某個(gè)字段的范圍將數(shù)據(jù)劃分到不同的數(shù)據(jù)庫中,例如按照用戶ID的范圍劃分。
2.按哈希分片
根據(jù)某個(gè)字段的哈希值將數(shù)據(jù)劃分到不同的數(shù)據(jù)庫中,例如根據(jù)用戶ID的哈希值劃分。
3.按列表分片
根據(jù)預(yù)定義的列表將數(shù)據(jù)劃分到不同的數(shù)據(jù)庫中,例如根據(jù)城市列表劃分用戶數(shù)據(jù)。
分庫分表實(shí)戰(zhàn)
下面是一個(gè)分庫分表的示例,演示如何使用MyCAT進(jìn)行分庫分表。
1.創(chuàng)建數(shù)據(jù)庫表
首先,創(chuàng)建需要進(jìn)行分庫分表的數(shù)據(jù)庫表,例如user表。
CREATE TABLE `user` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`name` VARCHAR(50) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB;
2.配置分片規(guī)則
在MyCAT的配置文件中,配置分片規(guī)則和數(shù)據(jù)節(jié)點(diǎn)信息。
如下所示:
<?xml versinotallow="1.0" encoding="UTF-8"?>
<!DOCTYPE mycat:config PUBLIC "-//MyCat//DTD MyCat config//EN" "http://mycat.io/dtd/mycat.dtd">
<mycat:config xmlns:mycat="http://mycat.io/schema/mycat-config"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://mycat.io/schema/mycat-config
http://mycat.io/schema/mycat-config.xsd">
<system>
<property name="schema" value="sharding_db"/>
</system>
<dataNode name="dn1" dataHost="localhost" database="db1" />
<dataNode name="dn2" dataHost="localhost" database="db2" />
<tableRule name="user_rule" dataNode="dn1,dn2">
<rule>
<columns>id</columns>
<algorithm>mod-long</algorithm>
</rule>
</tableRule>
</mycat:config>
在上述示例中,我們定義了兩個(gè)數(shù)據(jù)節(jié)點(diǎn)dn1和dn2,分別對應(yīng)了兩個(gè)后端MySQL數(shù)據(jù)庫db1和db2。
然后,我們定義了一個(gè)表規(guī)則:user_rule,使用mod-long算法將數(shù)據(jù)根據(jù)id字段進(jìn)行分片。
3.分庫分表代碼
在Java代碼中,使用JDBC連接到MyCAT數(shù)據(jù)庫,并執(zhí)行分庫分表的操作。
如下所示:
import java.sql.*;
public class MyCatShardingExample {
public static void main(String[] args) {
try {
// 連接MyCAT數(shù)據(jù)庫
String url = "jdbc:mysql://localhost:8066/sharding_db";
String username = "mycat_user";
String password = "mycat_password";
Connection conn = DriverManager.getConnection(url, username, password);
// 插入數(shù)據(jù)
String sql = "INSERT INTO user (name) VALUES (?)";
PreparedStatement statement = conn.prepareStatement(sql);
statement.setString(1, "John");
statement.executeUpdate();
// 查詢數(shù)據(jù)
String querySql = "SELECT * FROM user";
Statement queryStatement = conn.createStatement();
ResultSet resultSet = queryStatement.executeQuery(querySql);
while (resultSet.next()) {
int id = resultSet.getInt("id");
String name = resultSet.getString("name");
System.out.println("User ID: " + id + ", Name: " + name);
}
// 關(guān)閉連接
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
在上述示例中,我們使用JDBC連接字符串連接到MyCAT數(shù)據(jù)庫,并執(zhí)行了插入和查詢操作。
分庫分表注意
分庫分表后有幾點(diǎn)很重要,需要重視,比如:
- 數(shù)據(jù)分布策略:選擇合適的數(shù)據(jù)分布策略,避免數(shù)據(jù)傾斜;
- 復(fù)雜性增加:數(shù)據(jù)分布在多個(gè)庫、或表中,管理、和維護(hù)變得更加復(fù)雜;
- 事務(wù)處理困難:跨庫、或跨表的事務(wù)處理,難度陡增,還會需要分布式事務(wù)管理....等等,因?yàn)閿?shù)據(jù)已經(jīng)分布到:不同的環(huán)境、和服務(wù)器上了。
- 開發(fā)成本增加:需要修改、和優(yōu)化現(xiàn)有的數(shù)據(jù)庫訪問代碼,比如:需要引入中間件進(jìn)行路由,比如:(ShardingSphere、MyCat......等等)來簡化分庫分表的管理。