基于 MySQL + Tablestore 分层存储架构的大规模订单系统实践-SQL 查询和分析

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,高可用系列 2核4GB
简介: 前言前面我们介绍了基于 MySQL + Tablestore 分层架构的订单系统。订单数据储存进入 Tablestore 后,用户可以使用 SDK 中的 API 访问数据,也可以继续使用 SQL 访问 Tablestore 中的数据。Tablestore 提供了多种 SQL 的接入方式,客户可以通过 DLA 访问 Tablestore,也可以利用 Tablestore 自身对 SQL 的支持能力,

前言

前面我们介绍了基于 MySQL + Tablestore 分层架构的订单系统。订单数据储存进入 Tablestore 后,用户可以使用 SDK 中的 API 访问数据,也可以继续使用 SQL 访问 Tablestore 中的数据。Tablestore 提供了多种 SQL 的接入方式,客户可以通过 DLA 访问 Tablestore,也可以利用 Tablestore 自身对 SQL 的支持能力,直接使用 SQL 访问 Tablestore。

下面本文将展示,如何直接利用 SQL 直接读取 Tablestore 中的数据。

控制台使用SQL

添加自定义列

目前使用 SQL 需要将 Tablestore 中的数据列定义为预定义列。

进入表格存储控制台,点击进入实例。

点击进入对应的表 order_contract。

点击添加预定义列。将订单表字段均设置为预定义列,设置结果如图。

创建映射表

在控制台创建 order_contract 的映射表。在实例管理页面,点击 SQL 查询。可以看到 SQL 输入框。点击加号,选择表 order_contract。点击生成SQL

调整 SQL 的字段类型,在输入框输入以下建表 SQL。若有报错,可以尝试将 SQL 缩进至一行中,然后再执行。

create table order_contract (
oId VARCHAR(1024),
create_time VARCHAR(1024),
total_price DOUBLE,
p_brand VARCHAR(1024),
p_price DOUBLE,
pay_time BIGINT(20),
has_paid BIGINT(20),
s_id VARCHAR(1024),
p_name VARCHAR(1024),
c_id VARCHAR(1024),
c_name VARCHAR(1024),
s_name VARCHAR(1024),
p_count BIGINT(20),
p_id VARCHAR(1024),
primary key(oId));

点击刷新按钮,可以看到映射表已经建好。

页面查询

根据用户id查询订单

在SQL 输入框中输入以下 SQL。

select * from order_contract where c_id = "user1370786" limit 100

可以看到查询结果。

统计过去一段时间各店铺成交额

在SQL 输入框中输入以下 SQL。

select count(*) ,s_id from order_contract where pay_time > 1628784000000 group by s_id order by count(*) desc

可以看到查询结果。

性能比较

在 Tablestore 中压入 1亿 条订单记录,根据不同需求场景进行性能测试。

订单搜索、数据检索

需求分析

  • 根据订单id读取订单详情。
  • 搜索某店铺过去一段时间的订单例表。
  • 获取分页获取用户订单列表。
  • 搜索某用户购买过的包含某关键字的商品。

这一类需求为订单系统中最常见的数据检索需求。对于基于买家 id、订单 id、卖家 id 的数据检索,MySQL可以通过建立索引来解决,而对于多条件组合的查询,MySQL一般很难处理,需要通过 Elasticsearch 提供数据检索能力来对外提供搜索支持。

性能对比

下表中列举了几个常见场景下的数据检索需求,以及对应的 Tablestore SQL、MySQL的性能比较。可以看到 Tablestore SQL 在基于订单id、买家id、卖家id上的搜索性能可以与 MySQL 相媲美。而在一些复杂条件的搜索场景下,Tablestore SQL 基于多元索引,提供了比 MySQL 更加强大的检索能力,这一点是单独的 MySQL 架构无法提供的。

需要说明的是,MySQL 索引需要遵守最左匹配原则,一个索引可能只能应对一个或几个需求。因此在复杂组合检索条件下,可能需要构建很多索引表才能够满足检索需求,这不仅会占用很多磁盘空间,MySQL 的维护也会变得复杂。而 Tablestore SQL 底层基于多元索引,一张索引可以应对所有数据检索需求。

需求

Tablestore SQL / 执行时间

MySQL / 执行时间

说明

根据订单id获取订单详情

select * from order_contract where oId = "1623228187378_user978315"

执行时间:小于50ms

select * from order_contract where oId = "1623228187378_user978315"

执行时间:小于50ms

统计某店铺在 2021 年 6 月 30 日零点以来金额在 2000 元以上的订单,按订单金额倒序取前 20

select oId,c_id,c_name,c_name,p_brand,p_name,total_price,s_id from order_contract 

where s_id = 'store995' and pay_time > 1624982400000000

and total_price > 2000 ORDER BY total_price desc limit 20

执行时间: 亚秒至秒级

select oId,c_id, c_name,c_name, p_brand,p_name, total_price, s_id from order_contract where s_id = 'store995' and pay_time > '2021-06-30 00:00:00'

and total_price > 2000 ORDER BY total_price desc limit 20

执行时间在亚秒级

符合筛选条件的记录数1278。MySQL 建有 s_id,pay_time,total_price 联合索引。

统计某用户 2021 年 6 月 30 日零点以来金额在 2000 元以上的订单,按支付时间倒序取前 20

select oId,c_id,c_name,c_name,p_brand,p_name,total_price,s_id from order_contract where c_id = 'user2908110' and 

pay_time >= 1624982400000000

and total_price > 2000

order by pay_time desc limit 20

执行时间: 小于50ms

select oId,c_id,c_name,c_name,p_brand,p_name,total_price,s_id from order_contract where c_id = 'user2908110' and pay_time >= '2021-06-30 00:00:00'

and total_price > 2000

order by pay_time desc limit 20

执行时间小于 50ms

MySQL 在字段 c_id 上建立索引。

user2908110客户共有 14 张订单。

搜索2021年6月30日零点以来成交额在9995元以上,且商品品牌中包含特定关键字的订单,按商品单价倒序排列取前 100。

MySQL 中建立有p_price,total_price,pay_time的联合索引。

select oId,c_id,s_id,total_price,c_name,p_brand,pay_time,p_price from order_contract 

where total_price > 9995 and pay_time > 1624982400000000

and p_brand like "%品牌22%"

order by p_price desc limit 100

执行时间约 100 ms

select oId,c_id,s_id,total_price,c_name,p_brand,pay_time,p_price from order_contract 

where total_price > 9995 and pay_time > '2021-06-30 00:00:00'

and p_brand like "%品牌22%"

order by p_price desc limit 100

执行时间:分钟级

MySQL 在字段 p_price, total_price, pay_time 建有联合索引。

符合条件的记录数约16条

报表分析、运营推广

需求分析

  • 统计过去一个月各店铺成交额并排序;
  • 统计过去一个月各店铺成交的最大单笔订单金额;
  • 统计当天成交订单数最大的 100 位客户

此类需求在订单系统的报表工作、数据分析、运营推广当中会非常常见,主要考验数据库对聚合操作的支持能力。SQL 解析结合 Tablestore 的多元索引,在此类场景下的性能远高于 MySQL。

性能对比

表格中列举了三种依赖聚合操作的场景,对于每种场景,给出了各 SQL 语句以及运行时间。Tablestore SQL 在三种场景执行时间都在亚秒级,远远好于 MySQL 性能。三种场景下,MySQL 中都建立了适合此场景的联合索引,在有索引并无需回表的情况下,统计仍需要几十秒到几分钟的时间;而需要回表时,MySQL 性能会极速衰退。MySQL 索引需要遵守最左匹配原则,在现实环境当中,很难像这里的三个场景都建立了恰当的索引,甚至并不会建立类似于 pay_time, c_id, total_price 这样的联合索引,因此,现实场景大数据下 MySQL 对此类需求的支持能力更加糟糕。多元索引不需遵守最左匹配原则,可以以一份索引覆盖所有列,因此也不存在回表问题。

可以看到,在聚合场景下,Tablestore SQL 性能远高于 MySQL。

需求

Tablestore SQL / 执行时间

MySQL / 执行时间

说明

统计2021年6月30日零点以来,各店铺成交订单数量,订单数量降序排序。

select s_id, count(*) as c from order_contract where pay_time >= 1624982400000000  group by s_id order by c desc

执行时间: 亚秒级

select s_id, count(*) as c from order_contract where pay_time >= '2021-06-30 00:00:00'group by s_id order by c desc

执行时间约 25s

MySQL 建有 pay_time、s_id联合索引,无需回表。时间范围内记录数约1200w。

统计2021年6月30日零点以来,各店铺成交订单数量、总成交额、平均成交额、最大订单金额,按成交额降序排序。

select s_id, count(*),sum( total_price) as c, avg( total_price),max( total_price) 

from order_contract where pay_time >= 1624982400000000  group by s_id order by c desc

执行时间 :亚秒级

select s_id, count(*),sum( total_price) as c, avg( total_price),max( total_price) from order_contract where pay_time >= '2021-06-30 00:00:00'  group by s_id order by c desc

执行时间在一个小时以上

MySQL 建有 pay_time、s_id联合索引,需要回表。时间范围内记录数约1200w。

统计2021年6月30日零点以来,下单金额最高的100个客户。

SELECT c_id ,sum(total_price) as a FROM order_contract where pay_time >= 1624982400000000

group by c_id 

order by a desc limit 100

执行时间:亚秒级

SELECT c_id ,sum(total_price) as a FROM order_contract where pay_time >= '2021-06-30 00:00:00'

group by c_id 

order by a desc limit 100

执行时间约2分半

MySQL 建有pay_time, c_id, total_price 的联合索引,无需回表。时间范围内记录数约1200w。

总结

Tablestore 支持 SQL 查询。这使得用户开发工作、程序迁移工作,变得更加简单。SQL 解析,结合 Tablestore 的多元索引,为用户提供了更加强大的 SQL 查询、检索能力,其数据检索能力,远强于 MySQL。

相关实践学习
如何快速连接云数据库RDS MySQL
本场景介绍如何通过阿里云数据管理服务DMS快速连接云数据库RDS MySQL,然后进行数据表的CRUD操作。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
18天前
|
SQL 存储 关系型数据库
【MySQL基础篇】全面学习总结SQL语法、DataGrip安装教程
本文详细介绍了MySQL中的SQL语法,包括数据定义(DDL)、数据操作(DML)、数据查询(DQL)和数据控制(DCL)四个主要部分。内容涵盖了创建、修改和删除数据库、表以及表字段的操作,以及通过图形化工具DataGrip进行数据库管理和查询。此外,还讲解了数据的增、删、改、查操作,以及查询语句的条件、聚合函数、分组、排序和分页等知识点。
【MySQL基础篇】全面学习总结SQL语法、DataGrip安装教程
|
1月前
|
SQL 存储 缓存
MySQL进阶突击系列(02)一条更新SQL执行过程 | 讲透undoLog、redoLog、binLog日志三宝
本文详细介绍了MySQL中update SQL执行过程涉及的undoLog、redoLog和binLog三种日志的作用及其工作原理,包括它们如何确保数据的一致性和完整性,以及在事务提交过程中各自的角色。同时,文章还探讨了这些日志在故障恢复中的重要性,强调了合理配置相关参数对于提高系统稳定性的必要性。
|
1月前
|
SQL 关系型数据库 MySQL
MySQL 高级(进阶) SQL 语句
MySQL 提供了丰富的高级 SQL 语句功能,能够处理复杂的数据查询和管理需求。通过掌握窗口函数、子查询、联合查询、复杂连接操作和事务处理等高级技术,能够大幅提升数据库操作的效率和灵活性。在实际应用中,合理使用这些高级功能,可以更高效地管理和查询数据,满足多样化的业务需求。
156 3
|
1月前
|
SQL 关系型数据库 MySQL
MySQL导入.sql文件后数据库乱码问题
本文分析了导入.sql文件后数据库备注出现乱码的原因,包括字符集不匹配、备注内容编码问题及MySQL版本或配置问题,并提供了详细的解决步骤,如检查和统一字符集设置、修改客户端连接方式、检查MySQL配置等,确保导入过程顺利。
|
1月前
|
弹性计算 API 持续交付
后端服务架构的微服务化转型
本文旨在探讨后端服务从单体架构向微服务架构转型的过程,分析微服务架构的优势和面临的挑战。文章首先介绍单体架构的局限性,然后详细阐述微服务架构的核心概念及其在现代软件开发中的应用。通过对比两种架构,指出微服务化转型的必要性和实施策略。最后,讨论了微服务架构实施过程中可能遇到的问题及解决方案。
|
2月前
|
Cloud Native Devops 云计算
云计算的未来:云原生架构与微服务的革命####
【10月更文挑战第21天】 随着企业数字化转型的加速,云原生技术正迅速成为IT行业的新宠。本文深入探讨了云原生架构的核心理念、关键技术如容器化和微服务的优势,以及如何通过这些技术实现高效、灵活且可扩展的现代应用开发。我们将揭示云原生如何重塑软件开发流程,提升业务敏捷性,并探索其对企业IT架构的深远影响。 ####
56 3
|
2月前
|
Cloud Native 安全 数据安全/隐私保护
云原生架构下的微服务治理与挑战####
随着云计算技术的飞速发展,云原生架构以其高效、灵活、可扩展的特性成为现代企业IT架构的首选。本文聚焦于云原生环境下的微服务治理问题,探讨其在促进业务敏捷性的同时所面临的挑战及应对策略。通过分析微服务拆分、服务间通信、故障隔离与恢复等关键环节,本文旨在为读者提供一个关于如何在云原生环境中有效实施微服务治理的全面视角,助力企业在数字化转型的道路上稳健前行。 ####
|
1月前
|
Java 开发者 微服务
从单体到微服务:如何借助 Spring Cloud 实现架构转型
**Spring Cloud** 是一套基于 Spring 框架的**微服务架构解决方案**,它提供了一系列的工具和组件,帮助开发者快速构建分布式系统,尤其是微服务架构。
182 69
从单体到微服务:如何借助 Spring Cloud 实现架构转型
|
1月前
|
设计模式 负载均衡 监控
探索微服务架构下的API网关设计
在微服务的大潮中,API网关如同一座桥梁,连接着服务的提供者与消费者。本文将深入探讨API网关的核心功能、设计原则及实现策略,旨在为读者揭示如何构建一个高效、可靠的API网关。通过分析API网关在微服务架构中的作用和挑战,我们将了解到,一个优秀的API网关不仅要处理服务路由、负载均衡、认证授权等基础问题,还需考虑如何提升系统的可扩展性、安全性和可维护性。文章最后将提供实用的代码示例,帮助读者更好地理解和应用API网关的设计概念。
72 8
|
2月前
|
Dubbo Java 应用服务中间件
服务架构的演进:从单体到微服务的探索之旅
随着企业业务的不断拓展和复杂度的提升,对软件系统架构的要求也日益严苛。传统的架构模式在应对现代业务场景时逐渐暴露出诸多局限性,于是服务架构开启了持续演变之路。从单体架构的简易便捷,到分布式架构的模块化解耦,再到微服务架构的精细化管理,企业对技术的选择变得至关重要,尤其是 Spring Cloud 和 Dubbo 等微服务技术的对比和应用,直接影响着项目的成败。 本篇文章会从服务架构的演进开始分析,探索从单体项目到微服务项目的演变过程。然后也会对目前常见的微服务技术进行对比,找到目前市面上所常用的技术给大家进行讲解。
66 1
服务架构的演进:从单体到微服务的探索之旅