一直在说mysql数据大了要分库分表,但是一直都不知道分库分表如何计算表和库。
作用分表:降低单个表数据量太大带来性能的损失
分库:降低单个数据库机器带来性能的损失
分库分表:多个机器、多个表实现性能的提升
前提是库数量 * 每个库的表数量的总数不变
midValue = hash(分库分表的值,例如订单ID) % (库数量 * 每个库的表数量) 库序号 = midValue / 每个库的表数量 表序号 = midValue % 每个库的表数量简单计算
package com.tom.tom.mysql;
import java.util.function.Function;
import java.util.function.UnaryOperator;
public class MysqlDBTable {
public static void main(String[] args) {
UnaryOperator myHash = UnaryOperator.identity();
System.out.println("现在1个库,每个库256张表");
int dbNum = 1;
int tableNumInDb = 256;
int orderId = 1000;
System.out.println(orderId + " db index: " + getDbIndex(myHash, orderId, dbNum, tableNumInDb));
System.out.println(orderId + " table index: " + getTableIndex(myHash, orderId, dbNum, tableNumInDb));
orderId = 1100;
System.out.println(orderId + " db index: " + getDbIndex(myHash, orderId, dbNum, tableNumInDb));
System.out.println(orderId + " table index: " + getTableIndex(myHash, orderId, dbNum, tableNumInDb));
orderId = 128 + 256 * 23;
System.out.println(orderId + " db index: " + getDbIndex(myHash, orderId, dbNum, tableNumInDb));
System.out.println(orderId + " table index: " + getTableIndex(myHash, orderId, dbNum, tableNumInDb));
System.out.println("现在变成两个库,每个库128张表");
dbNum = 2;
tableNumInDb = 128;
orderId = 1000;
System.out.println(orderId + " db index: " + getDbIndex(myHash, orderId, dbNum, tableNumInDb));
System.out.println(orderId + " table index: " + getTableIndex(myHash, orderId, dbNum, tableNumInDb));
orderId = 1100;
System.out.println(orderId + " db index: " + getDbIndex(myHash, orderId, dbNum, tableNumInDb));
System.out.println(orderId + " table index: " + getTableIndex(myHash, orderId, dbNum, tableNumInDb));
orderId = 128 + 256 * 23;
System.out.println(orderId + " db index: " + getDbIndex(myHash, orderId, dbNum, tableNumInDb));
System.out.println(orderId + " table index: " + getTableIndex(myHash, orderId, dbNum, tableNumInDb));
}
public static int getDbIndex(Function hash, R r, int dbNum, int tableNumInDb) {
int mid = hash.apply(r) % (dbNum * tableNumInDb);
return mid / tableNumInDb;
}
public static int getTableIndex(Function hash, R r, int dbNum, int tableNumInDb) {
int mid = hash.apply(r) % (dbNum * tableNumInDb);
return mid % tableNumInDb;
}
}
现在1个库,每个库256张表 1000 db index: 0 1000 table index: 232 1100 db index: 0 1100 table index: 76 6016 db index: 0 6016 table index: 128 现在变成两个库,每个库128张表 1000 db index: 1 1000 table index: 104 1100 db index: 0 1100 table index: 76 6016 db index: 1 6016 table index: 0
可以看到在总的表数量不变的情况下,只迁移一半的表数据就可以了。
当数据库从2个变成4个的情况下,需要把第二个数据库中的表迁移到新的第三个和第4个表中。把第一个数据库中的表迁移一半到第二个表中。
现在1个库,每个库256张表 1000 db index: 0 1000 table index: 232 1100 db index: 0 1100 table index: 76 6016 db index: 0 6016 table index: 128 现在变成两个库,每个库128张表 1000 db index: 1 1000 table index: 104 1100 db index: 0 1100 table index: 76 6016 db index: 1 6016 table index: 0 现在变成4个库,每个库64张表 1000 db index: 3 1000 table index: 40 1100 db index: 1 1100 table index: 12 6016 db index: 2 6016 table index: 0



