阿里云 DRDS 分库分表二维查询解决方案(RANGE_HASH拆分函数)-阿里云开发者社区

开发者社区> knightzxh> 正文

阿里云 DRDS 分库分表二维查询解决方案(RANGE_HASH拆分函数)

简介:
+关注继续查看

现有互联网业务模式下,数据库分库分表已经成为解决数据库瓶颈的一个普遍的解决方案。分库分表有多种好处,比如高容量、大并发等,但是在拆分过程中也引入了一些使用限制,比如多维查询,非拆分键的查询请求会分发到底层所有实例进行查询,性能会大打折扣。

我们来举个例子,最常见的订单表,常用的拆分方法是按照用户 ID 作为拆分键。如果仅使用订单号作为条件来查询则会出现上述性能问题,而仅通过订单号的查询请求恰恰占有不小的比例。

在阿里云提供的新版 DRDS(5.1.28-1320920 及其以上的版本)已经实现二维查询的功能。看看他的特性 RANGE_HASH(COL1, COL2, N) :

  • 拆分键的类型必须是字符类型或数字类型
  • 根据任一拆分键后 N 位计算哈希值,然后再按分库数去取余,完成路由计算。N 为函数第三个参数。例如:RANGE_HASH(COL1, COL2, N) ,计算时会优先选择 COL1,截取其后N位进行计算。 COL1 不存在时找 COL2。
  • 适合于需要有两个拆分键,并且查询时仅有其中一个拆分键值的场景。
  • 两个拆分键皆不能修改。
  • 插入数据时如果发现两个拆分键指向不同的分库或分表时,插入会失败。

针对上一个例子,使用这个功能就可以解决问题。可以这样设计订单表,拆分键选择 user_id & order_id,在 order_id 中冗余 user_id 后 N 位。这样使用 RANGE_HASH(user_id, order_id, N) 功能即可以实现仅使用 user_id 或 order_id 条件就可以快速查询所需要的数据。

DRDS 表结构:

mysql> show create table test_order_rangehash\G
*************************** 1. row ***************************
       Table: test_order_rangehash
Create Table: CREATE TABLE `test_order_rangehash` (
  `id` int(11) NOT NULL AUTO_INCREMENT BY GROUP,
  `user_id` int(11) DEFAULT NULL,
  `order_id` bigint(20) DEFAULT NULL,
  `create_time` datetime DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `auto_shard_key_ORDER_ID` (`order_id`),
  KEY `auto_shard_key_USER_ID` (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 dbpartition by RANGE_HASH(`user_id`, `order_id`, 4)

底层数据库表结构:

mysql>show create table test_order_rangehash\G
*************************** 1. row ***************************
       Table: test_order_rangehash
Create Table: CREATE TABLE `test_order_rangehash` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `user_id` int(11) DEFAULT NULL,
  `order_id` bigint(20) DEFAULT NULL,
  `create_time` datetime DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `auto_shard_key_ORDER_ID` (`order_id`),
  KEY `auto_shard_key_USER_ID` (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8

拆分键所插入值指向不同分库即会报错:

mysql> insert into test_order_rangehash (user_id, order_id, create_time) values (100000001, 20170818111111100002,now());
ERROR 4300 (HY000): ERR-CODE: [TDDL-4300][ERR_ROUTE] Route : Range hash has mul rules, insert shard columns must be equal by rule. More: [http://middleware.alibaba-inc.com/faq/faqByFaqCode.html?faqCode=TDDL-4300]

仅使用 user_id 或 order_id 作为查询条件,均能准确定位到后段数据库:

mysql> explain select * from test_order_rangehash where user_id = 100000022\G
*************************** 1. row ***************************
GROUP_NAME: DCWEB_1498027405059FQIYDCWEB_JDLT_0022_RDS
       SQL: select `test_order_rangehash`.`id`,`test_order_rangehash`.`user_id`,`test_order_rangehash`.`order_id`,`test_order_rangehash`.`create_time` from `test_order_rangehash` where (`test_order_rangehash`.`user_id` = 100000022)
    PARAMS: {}
1 row in set (0.04 sec)

mysql> explain select * from test_order_rangehash where order_id = 2017081811113220022\G
*************************** 1. row ***************************
GROUP_NAME: DCWEB_1498027405059FQIYDCWEB_JDLT_0022_RDS
       SQL: select `test_order_rangehash`.`id`,`test_order_rangehash`.`user_id`,`test_order_rangehash`.`order_id`,`test_order_rangehash`.`create_time` from `test_order_rangehash` where (`test_order_rangehash`.`order_id` = 2017081811113220022)
    PARAMS: {}
1 row in set (0.03 sec)

结语:多维查询还可以使用异构索引来实现,但 RANGE_HASH 岂不更好。当然它不是万能的,某些场景下还是要选择异构索引(比如订单表以买家、卖家维度查询)。

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
十分钟教你了解阿里云数据库RDS
阿里云关系型数据库(Relational Database Service,简称RDS)是一种稳定可靠、可弹性伸缩的在线数据库服务。基于阿里云分布式文件系统和SSD盘高性能存储,RDS支持MySQL、SQL Server、PostgreSQL、PPAS(Postgre Plus Advanced Server,高度兼容Oracle数据库)和MariaDB TX引擎,并且提供了容灾、备份、恢复、监控、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。
544 0
独家对话阿里云函数计算负责人不瞋:你所不知道的 Serverless
日前,阿里云凭借函数计算产品能力全球第一的优势,入选 Forrester 2021 年第一季度 FaaS 平台评估报告,成为比肩亚马逊、全球前三的 FaaS 领导者。这也是首次有国内科技公司进入 FaaS 领导者象限。不瞋作为阿里云 Serverless 产品体系的负责人,也是国内 Serverless 的早期实践者。本文将呈现这次访谈的完整总结。
764 0
阿里云函数计算发送短信单文件轻量版
本文实现了使用阿里云《函数计算》+《短信服务》发送短信的简单功能,官方短信服务SDK功能全面,但较为冗杂,二爷精简了官方SDK,实现了一段代码(单文件)发送短信的功能。 阅读本文,你需要先了解阿里云函数计算、阿里云短信服务的基本常识。 试用本代码,需要预先在短信服务中申请短信签名、短信模板。
2393 0
HBase查询优化之Short-Circuit Local Reads
1.概述 在《HBase查询优化》一文中,介绍了基于HBase层面的读取优化。由于HBase的实际数据是以HFile的形式,存储在HDFS上。那么,HDFS层面也有它自己的优化点,即:Short-Circuit Local Reads。
1383 0
有效解决VC++6.0一个工程不能有多个main函数的解决方案
一.现象及原因 现象:在一个工程中有2个带有main函数的文件:InsertSort.cpp,ShellSort.cpp InsertSort.cpp 1 #include 2 3 void InsertSort(int A[],int n) 4 { 5 i...
1012 0
数论 代数 群论 范畴论 与 函数式编程 Haskell, Scala
来自China Scala User Group 微信群的一段话,讲的很有意思,这里摘录一下: 数论 研究一个一个的数特性;Object常用术语: 1, 2, 3, "hello world" 代数 研究数上面的操作的特性;常用术语:+ ,-, * , /, mod, concat, 群论 把代数上面的操作,根据共通的特性,分成一个组(群)一个组(群)的来研究。
1606 0
PHPpraffa也有了,一个PHP版本的阿里云函数计算与API网关的开发框架
发布了Python版本的函数计算与API网关的开发框架后,一直觉得对不起PHP,因为公司一直是用PHP的,我这弄了个Python,实在不该,对了,(Python版本说明点这里。 PHPpraffa是什么? PHPpraffa 是praffa的PHP版本。
1161 0
使用阿里云Serverless函数计算实现HTTP健康检查+故障短信通知
定时对网站/API进行请求,根据请求响应判断服务是否可用,网站是否存在宕机,当发生宕机时,发送短信通知管理员.
1083 0
JavaScript 函数
函数是由事件驱动的或者当它被调用时执行的可重复使用的代码块。 # JavaScript 函数语法 函数就是包裹在花括号中的代码块,前面使用了关键词 function:function functionname() { 执行代码 } 当调用该函数时,会执行函数内的代码。
1289 0
+关注
12
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
《2021云上架构与运维峰会演讲合集》
立即下载
《零基础CSS入门教程》
立即下载
《零基础HTML入门教程》
立即下载