MyCat08——分片技术之垂直拆分

2023-11-25 17:21:20 浏览数 (2)

1 问题

随着我们的系统用户不断增加,产出的内容和数据量将不断增长,单台数据库数据量因为过大,将会导致查询速率降低,严重影响用户体验。

为了提高查询速度,可以优化查询的SQL语句,加大数据库服务器的内存,优化数据库表结构和索引,虽然能从一定程度上使效率得到提升,但对于数据记录达到千万级的数据表,其优化的效果仍会大打折扣。

2 垂直拆分

2.1 垂直分表

将数据表按列拆分,可将一张列比较多的表拆分为多张表。

当一个表记录虽不多,但字段较多,致使表占用的空间大,检索表的时候会占用大量的IO,严重降低数据库性能。此时,就可以把该表拆分为多个不同的表,这些多个表,应与原表保持一对一的关系。

拆分的原则:

  • 把不常用的字段单独放在一张表;
  • 把 text, blob 等含有大量信息的字段拆分出来放在附表中;
  • 经常组合查询的列,放在同一张表中。

如下用户表中

如果只想要查询昵称为“孙悟空”的用户名,可以使用SQL语句:

SELECT 用户名 FROM 用户表 where 昵称=孙悟空;

这里虽然仅查询了用户名,但是在对记录进行扫描时,地址和订单信息这两个含有大量信息的字段也会被扫描到,增加了性能损耗。此时就是可以使用垂直拆分,将不想查询的字段拆分到另外的表中。

出现这种问题,多是因为最初对数据表的设计不合理导致。如果做好表的设计,该种拆分方式目前的应用并不多。

2.2 垂直分库

以数据表为区分依据,将实现不同业务的表,拆分到不同的数据库分片中。这种拆分方式应用最广。

不同数据库分片拥有不同的数据表,数据库的名称相同,我们的全量数据等于所有数据库分片的并集。

3 垂直拆分的实现

3.1 修改配置

修改 schema.xml 文件。

3.1.1 schema节点

在 schema 节点中将 dataNode 属性配置为 dn1;

并在 schema 下增加 table 节点,并配置以下属性:

  • name 需要单独配置的数据表名称
  • dataNode 需要单独配置的数据表所在服务器节点,如 dn2

在 table 节点设置的表,将存储在 dn2 节点,而没有被列出的表,都将存储在 dn1 节点。

3.1.2 dataNode节点

该节点用于分片设置。

一个分片节点对应于一条 dataNode 设置。所有 dataNode 节点应配置为同一个 database。

3.1.3 dataHost节点

dataHost 节点名称应与上一步中配置的 dataNode 节点中 dataHost 一致,且数量也应一致,这里应配置两个 dataHost 节点。

为了简化配置,删掉之前做的实现读写分离相关的配置信息。

修改后的配置信息如下:

3.2 创建数据库

为了简化学习难度,这里需要删除之前的相关服务并重新安装MYSQL。

3.2.1 环境清理

清理之前做双主双从数据库。

停止所有docker容器

docker stop $(docker ps -qa)

删除所有docker容器

docker rm $(docker ps -qa)

删除完成后,通过以下指令已查询不到任何容器

docker ps -a

3.2.2 安装数据库

以容器方式安装两个数据库服务:db1 和 db2

docker run -d -p 3366:3306 -e MYSQL_ROOT_PASSWORD=123456 --name=db1 mysql:5.7

docker run -d -p 3366:3306 -e MYSQL_ROOT_PASSWORD=123456 --name=db1 mysql:5.7

3.2.3 创建数据库

在数据库db1和db2中分别创建数据库 orders。

docker exec -it db1 /bin/bash

mysql -uroot -p123456

create database orders;

4 环境验证

4.1 启动mycat

使用mycat指令启动服务。

mycat start

如果服务启动失败,可以到 logs 目录下查看日志。

一般错误日志会输出到 .gz 后缀的压缩文件中,可以使用 gunzip 指令解压后查看。

4.2 进入mycat数据端口

mysql -uroot -p123456 -h192.168.137.3 -P8066

4.3 创建数据表

执行创建表的SQL语句。

创建customers表

create table customers(id int auto_increment primary key, name varchar(200));

创建orders表

create table orders(id int auto_increment primary key, order_type int, customer_id int, amount decimal(10,2));

在db1中查看数据表

在db2中查看数据表

在mycat中查看数据表

4.4 需要注意的是

db2中看到表名为全大写 CUSTOMERS,

而mycat中表名为 customers,

如果要在mycat中操作db2中CUSTOMERS 表的数据时,表名需要大写,才能访问到db2库的数据。

猜测可能是mycat的一个BUG。

我正在参与2023腾讯技术创作特训营第三期有奖征文,组队打卡瓜分大奖!

0 人点赞