一个数据库由很多表的构成,每个表对应着不同的业务,垂直切分是指按照业 务将表进行分类,分布到不同 的数据库上面,这样也就将数据或者说压力分担到不同的库上面
#1. 如何分库
一个问题:在两台主机上的两个数据库中的表,能否关联查询? 答案:不可以关联查询。 分库的原则:有紧密关联关系的表应该在一个库里,相互没有关联关系的表可以分到 不同的库里。
#客户表 rows:20万 CREATE TABLE customer(
id INT AUTO_INCREMENT,
NAME VARCHAR(200),
PRIMARY KEY(id)
);
#订单表 rows:600万 CREATE TABLE orders(
id INT AUTO_INCREMENT,
order_type INT,
customer_id INT,
amount DECIMAL(10,2),
PRIMARY KEY(id)
);
#订单详细表 rows:600万 CREATE TABLE orders_detail(
id INT AUTO_INCREMENT,
detail VARCHAR(2000),
order_id INT,
PRIMARY KEY(id)
);
#订单状态字典表 rows:20 CREATE TABLE dict_order_type(
id INT AUTO_INCREMENT,
order_type VARCHAR(200),
PRIMARY KEY(id)
);
以上四个表如何分库?客户表分在一个数据库,另外三张都需要关联查询,分在另外 一个数据库,这样才符合上面说的,订单相关的三张表有关联关系,如果分在了不同的数据库,那肯定就没法关联查询了。
#2. 如何分表
##2.1 选择要拆分的表 MySQL 单表存储数据条数是有瓶颈的,单表达到 1000 万条数据就达到了瓶颈,会 影响查询效率,需要进行水平拆分(分表)进行优化。 例如:例子中的 orders、orders_detail 都已经达到 600 万行数据,需要进行分表 优化。
##2.2 分表字段
而一般的不像是订单这种注重时效的数据,我们其实可以采用第一种方式,以id或者创建时间来分表,这样也可以达到分表的目的,总之我们要以目的为导向,不然最后分了表发现性能还是有问题。
#3. 实现分库分表
Mycat2 一大优势就是可以在终端直接创建数据源、集群、库表,并在创建时指定 分库、分表。与 1.6 版本比大大简化了分库分表的操作
##3.1 添加数据库、存储数据源
/*+ mycat:createDataSource{
"name":"dw0",
"url":"jdbc:mysql://192.168.140.100:3306", "user":"root",
"password":"123123"
} */;
/*+ mycat:createDataSource{
"name":"dr0", "url":"jdbc:mysql://192.168.140.100:3306", "user":"root",
"password":"123123"
} */;
/*+ mycat:createDataSource{ "name":"dw1", "url":"jdbc:mysql://192.168.140.99:3306", "user":"root",
"password":"123123"
} */;
/*+ mycat:createDataSource{ "name":"dr1", "url":"jdbc:mysql://192.168.140.99:3306", "user":"root",
"password":"123123"
} */;
#通过注释命名添加数据源后,在对应目录会生成相关配置文件 cd /usr/local/mycat/conf/datasources
#如下图
##3.2 添加集群配置
把新添加的数据源配置成集群
#//在 mycat 终端输入
/*! mycat:createCluster{"name":"c0","masters":["dw0"],"replicas":["dr0"]} */;
/*! mycat:createCluster{"name":"c1","masters":["dw1"],"replicas":["dr1"]} */;
#可以查看集群配置信息
cd /usr/local/mycat/conf/clusters #如下图
##3.3 创建全局表
#添加数据库db1 CREATE DATABASE db1;
#在建表语句中加上关键字 BROADCAST(广播,即为全局表) CREATE TABLE db1.`travelrecord` (
`id` bigint NOT NULL AUTO_INCREMENT, `user_id` varchar(100) DEFAULT NULL, `traveldate` date DEFAULT NULL, `fee` decimal(10,0) DEFAULT NULL, `days` int DEFAULT NULL,
`blob` longblob,
PRIMARY KEY (`id`),
KEY `id` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 BROADCAST; #进入相关目录查看 schema 配置
vim /usr/local/mycat/conf/schemas/db1.schema.json #可以看到自动生成的全局表配置信息
##3.4 创建分片表(分库分表)
#在 Mycat 终端直接运行建表语句进行数据分片 CREATE TABLE db1.orders(
id BIGINT NOT NULL AUTO_INCREMENT, order_type INT,
customer_id INT,
amount DECIMAL(10,2),
PRIMARY KEY(id),
KEY `id` (`id`)
)ENGINE=INNODB DEFAULT CHARSET=utf8
dbpartition BY mod_hash(customer_id) tbpartition BY mod_hash(customer_id) tbpartitions 1 dbpartitions 2;
#数据库分片规则,表分片规则,以及各分多少片
INSERT INTO orders(id,order_type,customer_id,amount)
VALUES(1,101,100,100100);
INSERT INTO orders(id,order_type,customer_id,amount) VALUES(2,101,100,100300);
INSERT INTO orders(id,order_type,customer_id,amount) VALUES(3,101,101,120000);
INSERT INTO orders(id,order_type,customer_id,amount) VALUES(4,101,101,103000);
INSERT INTO orders(id,order_type,customer_id,amount) VALUES(5,102,101,100400);
INSERT INTO orders(id,order_type,customer_id,amount) VALUES(6,102,100,100020);
SELECT * FROM orders;
#同样可以查看生成的配置信息
#进入相关目录查看 schema 配置
vim /usr/local/mycat/conf/schemas/db1.schema.json
##3.5 创建ER表
上述两表具有相同的分片算法,但是分片字段不相同 Mycat2 在涉及这两个表的 join 分片字段等价关系的时候可以完成 join 的下推