在MySQL中,隨著業(yè)務(wù)數(shù)據(jù)的增長,單個數(shù)據(jù)庫可能無法應(yīng)對高并發(fā)、海量數(shù)據(jù)的處理請求。一種有效的解決方案是采用分庫分表的方式將數(shù)據(jù)分散到多個數(shù)據(jù)庫中進(jìn)行存儲和查詢。
下面介紹幾種常見的分庫分表實現(xiàn)方案:
1. 垂直分庫
CREATE DATABASE db1; -- 創(chuàng)建數(shù)據(jù)庫1 CREATE DATABASE db2; -- 創(chuàng)建數(shù)據(jù)庫2 -- 將原數(shù)據(jù)表按照業(yè)務(wù)關(guān)系拆分到不同的數(shù)據(jù)庫中 CREATE TABLE db1.user_info ( id INT(11) NOT NULL AUTO_INCREMENT, name VARCHAR(50), PRIMARY KEY (id) ); CREATE TABLE db2.order_info ( id INT(11) NOT NULL AUTO_INCREMENT, user_id INT(11), order_date DATE, PRIMARY KEY (id), INDEX (user_id) );
垂直分庫將原來的單個數(shù)據(jù)庫中的數(shù)據(jù)表按照業(yè)務(wù)拆分到多個不同的數(shù)據(jù)庫中。這種方式可以將不同的數(shù)據(jù)表放到不同的數(shù)據(jù)庫,更好的進(jìn)行數(shù)據(jù)隔離、資源隔離。但是,垂直分庫過度劃分?jǐn)?shù)據(jù)表可能會增加數(shù)據(jù)庫之間的關(guān)聯(lián)關(guān)系,增加系統(tǒng)復(fù)雜度。
2. 水平分表
CREATE TABLE user_info ( id INT(11) NOT NULL AUTO_INCREMENT, name VARCHAR(50), PRIMARY KEY (id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 PARTITION BY HASH(id) PARTITIONS 5; CREATE TABLE order_info ( id INT(11) NOT NULL AUTO_INCREMENT, user_id INT(11), order_date DATE, PRIMARY KEY (id), INDEX (user_id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 PARTITION BY RANGE(order_date)( PARTITION p0 VALUES LESS THAN ('2020-01-01'), PARTITION p1 VALUES LESS THAN ('2021-01-01'), PARTITION p2 VALUES LESS THAN ('2022-01-01'), PARTITION p3 VALUES LESS THAN ('2023-01-01'), PARTITION p4 VALUES LESS THAN MAXVALUE );
水平分表將單個數(shù)據(jù)表按照水平方向進(jìn)行切分,把數(shù)據(jù)分散到多個服務(wù)器或多個不同的數(shù)據(jù)表中存儲。這種方式可以擴展單個數(shù)據(jù)表的存儲容量,提高數(shù)據(jù)讀寫的性能。但是,水平分表對于表之間的關(guān)聯(lián)查詢可能會帶來一些麻煩。
3. 水平分庫
-- 創(chuàng)建數(shù)據(jù)表路由表 CREATE TABLE db_route ( id INT(11) NOT NULL AUTO_INCREMENT, db_name VARCHAR(50), PRIMARY KEY (id) ); INSERT INTO db_route (db_name) VALUES ('db1'), ('db2'), ('db3'); CREATE TABLE user_info ( id INT(11) NOT NULL AUTO_INCREMENT, name VARCHAR(50), PRIMARY KEY (id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 PARTITION BY HASH(id) PARTITIONS 5; CREATE TABLE order_info ( id INT(11) NOT NULL AUTO_INCREMENT, user_id INT(11), order_date DATE, PRIMARY KEY (id), INDEX (user_id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 PARTITION BY RANGE(order_date)( PARTITION p0 VALUES LESS THAN ('2020-01-01'), PARTITION p1 VALUES LESS THAN ('2021-01-01'), PARTITION p2 VALUES LESS THAN ('2022-01-01'), PARTITION p3 VALUES LESS THAN ('2023-01-01'), PARTITION p4 VALUES LESS THAN MAXVALUE );
水平分庫將整個數(shù)據(jù)庫按照業(yè)務(wù)拆分到多個不同的數(shù)據(jù)庫中。同樣的,需要建立數(shù)據(jù)表路由表,根據(jù)路由表來確定數(shù)據(jù)表的存儲位置。這種方式相對于垂直切割和水平切割來說,引入了更多的數(shù)據(jù)表之間的關(guān)聯(lián)查詢問題,比較適合于需要管理多個實例的大型系統(tǒng)。