开发者社区> 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 岂不更好。当然它不是万能的,某些场景下还是要选择异构索引(比如订单表以买家、卖家维度查询)。

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

相关文章
阿里云商标注册查询小程序上线及使用方法
阿里云商标查询小程序上线(来看看支持哪些功能),商标查询可以使用阿里云商标查询微信小程序,可以查询到商标信息和商标注册风险,输入商标名称、注册号、申请人即可查询,输入商标名称可以一键查询注册风险,阿里云百科分阿里云商标查询小程序入口及使用方法教程:
104 0
阿里云商标注册查询入口官网_商标申请流程新手步骤
阿里云商标注册图文教程快速上手笔记,本文以阿里云商标智能注册申请为例,商标智能注册申请需要用户手动填写商标类型、商标名称、商标图样、商标说明及商标分类表选择等操作,流程较为复杂,TM83商标网来详细说下阿里云商标注册快速上手笔记。阿里云商标注册分为智能注册申请、顾问注册和安心注册:顾问注册和安心注册会有阿里云商标顾问提供一对一服务,所以价格相对智能注册要贵一些,智能注册价格275元、商标顾问注册申请680元、商标安心注册申请1580元,安心注册比顾问注册多了一个不成功全额退款服务,所以安心注册费用相对更高一些。
160 0
阿里云-DataWorks- ODPS SQL开发3-日期与字符、数学运算、聚合函数函数
阿里云-DataWorks- ODPS SQL开发3 本文主要讲解日常大量会接触到的一些常用的日期与字符、数学运算、聚合函数函数。
1093 0
阿里云商标注册查询微信小程序有用过的吗?很好用呀
商标查询可以使用阿里云商标查询微信小程序,可以查询到商标信息和商标注册风险,输入商标名称、注册号、申请人即可查询,输入商标名称可以一键查询注册风险,阿里云百科分阿里云商标查询小程序入口及使用方法教程:
62 0
阿里云注册域名没有查询到可用的信息模板解决方法
阿里云注册域名之前需要先创建信息模版,并且完成域名持有者身份信息核验,才可以注册域名,阿里云域名注册将采用先完成域名持有者身份信息核验、再注册域名的方式。注册域名时需要选择域名持有者,域名持有者可以是个人或企业,如果你的阿里云账号下没有已实名认证的信息模版,那么注册域名时会提示“亲,没有查询到可用的信息模板”
221 0
阿里云上云礼包优惠券领取、查询、使用及限制说明
阿里云提供个人上云礼包和企业上云礼包,阿里云百科分享阿里云优惠券领取、查看、使用及限制说明
163 0
阿里云域名查询注册实名认证和备案全过程
阿里云域名查询、域名注册、域名实名认证和域名备案全过程:
203 0
如何查询阿里云账号uid?
阿里云账号UID查询方法
1121 0
阿里云管局审核需要多长时间?精准天数查询
阿里云网站备案初审通过提交到管局,管局审核时间为1到20天,在阿里云备案系统中可以查询到精准审核时间
349 0
阿里云域名查询、域名注册、域名实名认证和域名备案全过程
阿里云域名查询、域名注册、域名实名认证和域名备案全过程
1367 0
+关注
knightzxh
文章
问答
视频
文章排行榜
最热
最新
相关电子书
更多
阿里云云原生Serverless产品手册
立即下载
低代码开发师(初级)实战教程
立即下载
阿里巴巴DevOps 最佳实践手册
立即下载