白菜Java自习室 涵盖核心知识mysql
分库分表难题(一) 分表分页/跨库分页 难玩却不表明没有玩法
分库分表难题(二) 跨库/跨实例 Join 链接 不是非得依赖中间件算法
某电商公司原先将会员、订单、商品等数据都存放在一个数据库实例中,但业务发展迅猛,访问量极速增加,致使数据库容量及性能遭遇瓶颈,所以 用户决定对架构进行垂直拆分,将会员、商品、订单数据垂直拆分至三个数据库实例中。此时业务上须要展现某个品类商品的售卖订单量,本来在同一数据库里的查询,要变成跨两个数据库实例的查询。业务上要怎么进行关联查询?sql
用户首先想到的方法是,对现有业务代码进行重构,分别从两个数据库查询数据,而后在业务代码中进行 join 关联。那么问题来了,若是采用这个解决方案,业务上那么多查询改造起来,拆分难度极大,操做起来过于复杂。跨库 join 操做又没有很是高效的办法,须要从各个业务库迭代查询,查询效率也会有必定影响。docker
当方案被否决后,用户再次想到的方法是,要不 使用 Mycat,Sharding-jdbc 等数据库中间件来实现,固然这自己是一个可行的方案,并且也是不错的解决方案。可是若是公司系统状况复杂,改变架构困难,代码腐化严重,短期内根本没法解决这个问题,脱离这些数据库中间件是否是就一筹莫展了呢?数据库
如图,FEDERATED 引擎的原理为:缓存
MySQL 的前置安装过程这里就省略了,版本是推荐 MySQL5.7。服务器
Docker 方式安装过程可参考做者文章: Canal 解决 MySQL 和 Redis 数据同步问题markdown
查看 mysql 数据库中 Federated 引擎是否开启。下图所示,为未开启。架构
SHOW ENGINES;
复制代码
修改 mysql 文件夹根目录的 my.ini 文件(Linux 系统修改 my.cnf 文件):新添加一行,内容为 federated,以下图所示:(Docker 方式安装只须要修改外置配置文件后重启容器便可,阿里云、华为云 DMS 可自行寻找修改配置方式,甚至于自带跨库Link功能)less
federated
复制代码
docker restart (容器ID)
复制代码
检查 mysql 数据库中 Federated 引擎是否开启,如今咱们发现已是开启状态了。
SHOW ENGINES;
复制代码
这里读者自行去建数据库,自由发挥:
而后 在两个数据库里分别新建两张表 prd_sku(SKU信息表)和 prd_sku_stock(SKU库存表):
CREATE TABLE `prd_sku` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键',
`name` varchar(180) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT 'SKU名称',
`code` varchar(180) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT 'SKU编码',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci ROW_FORMAT = Dynamic;
复制代码
CREATE TABLE `prd_sku_stock` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键',
`sku_id` int(11) NOT NULL DEFAULT 0 COMMENT 'SKU的ID',
`stock` int(11) NOT NULL DEFAULT 0 COMMENT 'SKU的库存',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci ROW_FORMAT = Dynamic;
复制代码
咱们先在表里边添加点数据进去:
INSERT INTO `prd_sku` VALUES (1, '黄色S码', 'Y00S00');
INSERT INTO `prd_sku` VALUES (2, '红色M码', 'R00M00');
复制代码
INSERT INTO `prd_sku_stock` VALUES (1, 1, 96);
INSERT INTO `prd_sku_stock` VALUES (2, 2, 98);
复制代码
CREATE TABLE `mycat_db1`.`prd_sku_stock` (
`id` int(0) NOT NULL AUTO_INCREMENT,
`sku_id` int(0) NOT NULL,
`stock` int(0) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE = FEDERATED CONNECTION = 'mysql://root:88021120@localhost:3306/mycat_db2/prd_sku_stock';
复制代码
这里有几个特别须要注意的点:
SELECT * FROM prd_sku t1, prd_sku_stock t2 WHERE t1.id=t2.sku_id;
复制代码
阿里云 DMS(数据管理)跨实例查询服务,不只覆盖了异构数据源关联查询的场景,还解决了跨 region、跨云的数据库关联查询的难题。不只如此,还对查询性能进行了大幅优化,使得大部分查询能在毫秒级完成。用户无需经过数据聚集,便可经过标准的 SQL 实现跨实例的交叉查询。
熟悉 Oracle 的人应该知道,咱们能够在当前登陆的 Oracle 上,创建一个 DBLink 指向另外一个远程的Oracle 数据库表。在跨实例查询服务中,从新定义了 DBLink 的概念,它是一个指向用户的任意数据库实例的虚拟链接,是数据库实例的别名。例如,对于 MySQL 来讲,DBLink 和 ip/port 一一对应。借助 DBLink,便可实现对任意数据源的 SQL 访问。
经过标准的 SQL 语句,便可实现跨实例查询。同时跨实例查询服务高度兼容 MySQL,支持 MySQL 协议,以及各类经常使用函数和语法。您可经过 JDBC/ODBC 驱动链接到跨实例查询服务;也可使用各类 MySQL GUI 工具来管理各类数据源。
跨实例查询是无服务器化的在线数据库关联查询服务。用户无需预购计算资源、无需维护资源、没有运维和升级成本,随时随地使用。
跨实例查询服务底层基于强大的 MPP 计算引擎,持续不断地对 SQL 查询进行优化,包括 pushdown、join 算法、执行计划缓存、Meta 缓存、本地调度、链接池等技术。目前单表查询以及跨实例的多表关联查询,都能在毫秒级完成。
目前已支持 MySQL、SQLServer、PostgreSQL 等多种关系型数据库。
除了关系型数据库以外,跨实例查询还支持以 SQL 方式访问 Redis 等 NoSQL 数据库。因为支持了 SQL 语法,也能够实现 RDBMS 和 NoSQL 之间关联查询。是的,你没看错,一条 SQL 就能实现 MySQL 和 Redis 之间的关联查询。
企业发展到必定阶段,用户量、业务量不断攀升,原来的单机房容量已经不能知足业务发展的需求,再结合容灾、高可用等因素,一般会选择跨 region 部署,也叫单元化部署。同时,很多企业也须要将业务拓展到海外,经过本地就近部署,为国外用户提供更好的体验。相似这种水平拆分带来的问题就是,如何对全局的业务数据进行统一的汇总关联查询。
借助 DMS 跨实例查询服务,不管您的数据库实例部署在阿里云的哪一个 region,无需跨 region 的数据迁移,便可实现全部 region 数据的统一查询。除了阿里云 RDS,也支持用户部署在阿里云 ECS 上的各类数据库。不只如此,若是您的数据库部署在本地 IDC 机房,甚至其余云厂商,均可以经过跨实例查询服务,实现这些混合云场景的跨实例关联查询。
分库分表难题(一) 分表分页/跨库分页 难玩却不表明没有玩法
分库分表难题(二) 跨库/跨实例 Join 链接 不是非得依赖中间件