【笔记】开发指南—函数—拆分函数—STR_HASH

简介: 本文将介绍STR_HASH函数使用方式

描述

STR_HASH函数通过指定字符串的开始位置下标与结束下标,以截取拆分键的字符串的某段子串,然后将其作为字符串(或整数)输入进行分库分表的路由计算具体的物理分片,函数如下所示:


STR_HASH( shardKey [, startIndex, endIndex [, valType [, randSeed ] ] ] )
参数 说明
shardKey 拆分键列的列名。
startIndex 目标子串的开始位置的下标。取值从0开始(即原字符串的第1个字符的下标用0表示),默认值为-1(即不做任何截取)。
endIndex 目标子串的结束位置的下标。取值从0开始(即原字符串的第1个字符的下标用0表示),默认值为-1(即不做任何截取)。

startIndex和endIndex时需注意如下几种取值情况:

  • 当startIndex == j && endIndex = k (j>=0, k>=0 ,k>j)时,表示截取原字符串的[ j, k )区间的字符串作为子串。例如:
    • 对于字符串ABCDEFG,子串区间[1,5)的值是BCDE。
    • 对于字符串ABCDEFG,,子串区间[2,2)的值是''。
    • 对于字符串ABCDEFG,子串区间[4,100)的值是EFG。
    • 对于字符串 ABCDEFG,子串区间[100,105)的值是''。
  • 当startIndex == -1 && endIndex = k (k>=0)时,表示截取原字符串最后k个字符作为子串,原字符串不足k个字符则直接获取整个字符串。
  • 当startIndex = k && endIndex == -1 (k>=0)时,表示截取原字符串开头k个字符作为子串,原字符串不足k个字符则直接获取整个字符串。
  • 当startIndex == -1 && endIndex == -1时, 表示不做任何截取,子串与原字符串完全一致。
valType 表示截取后的子串在计算分库分表时所使用的类型,取值范围如下:
  • 0(默认值):表示PolarDB-X将截取后的子串当作字符串类型来计算路由。
  • 1:表示PolarDB-X将截取后的子串当作整数类型来计算路由(子串面值的整数不能大于9223372036854775807,也不支持浮点数)
randSeed 当子串以字符串类型来计算路由的哈希值时PolarDB-X所使用的随机种子的值,通常不用需要填写,仅当用于使用默认值随机种子(randSeed=31)的STR_HASH在实际业务中出现路由不均衡的场景,达到用哈希均衡数据的目的。该参数默认值为31,可取其他值(如131,13131,1313131等)。

说明

  • 仅当valType取值为0时,才支持配置该参数。
  • 该参数调整后您需要手动将所有数据导出来,再将新的拆分算法导入数据(即您需要对数据进行重分布)。

注意事项

使用STR_HASH做拆分的表仅适用于点查场景,如果在业务中范围查询,则会接直接触发全表扫描导致慢查询。

使用限制

  • 拆分键的数据类型需为字符串类型(CHAR或VARCHAR)。
  • 不支持在建表完成后再调整STR_HASH的参数。

使用场景

  • 实现一个分表(或分库)只对应一个拆分表键的取值(字符串类型)的精准路由效果。例如,某个互联网金融应用是按年月(YYYYMM)分库,然后按订单号分表,该应用的订单号有个特点,就是订单号的最后3位字符串是一个整数,其取值范围是000~999。该应用的需求是需要在一个物理分库内,要将订单号后3位的每一个数值只单独路由到一个物理分表。那么,该应用分库采用YYYYMM,然后分表采用拆分函数STR_HASH,每个库1024个分表,就可以达到效果。具体的SQL语句如下:
create table test_str_hash_tb (

id int NOT NULL AUTO_INCREMENT,
order_id varchar(30) NOT NULL,
create_time datetime DEFAULT NULL,
primary key(id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
dbpartition by YYYYMM(`create_time`)
tbpartition by STR_HASH(`order_id`, -1, 3, 1) tbpartitions 1024;
  • 应用采用这样建表SQL,原因是分表的字符串截取后3位并转换为整数(整数范围是000~999)后再取模做分表路由(共1024个分表),其路由结果能保证每一个物理分表只对一个拆分建的取值。而原来PolarDB-X默认拆分函数HASH无法达到这样的效果,是因为字符串经过hashCode计算后的整数是不可预知的,有可能会出现一个物理分表要对应多个不同拆分建的取值。
  • STR_HASH拆分函数适用于使用字符串类型作为拆分键并且是绝大部分都是点查的场景,如根据ID查交易订单、物流订单等。

使用示例

假设order_id的类型为VARCHAR(32),现在需要将order_id作为拆分键,计划分4个库,分8个表。

  • 假设需要使用order_id的最后4位的字符串作为整数来计算分库分表路由,则您可以使用如下SQL进行建表。
create table test_str_hash_tb (    
id int NOT NULL AUTO_INCREMENT,
order_id varchar(32) NOT NULL,
create_time datetime DEFAULT NULL,
primary key(id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
dbpartition by STR_HASH(`order_id`, -1, 4, 1)
tbpartition by STR_HASH(`order_id`, -1, 4, 1) tbpartitions 2;
  • 假设需要截取order_id的第3个字符(即starIndex=2)与第7个字符(即endIndex=7)之间子串来计算分库分表路由,则您可以使用如SQL进行建表。
create table test_str_hash_tb (    
id int NOT NULL AUTO_INCREMENT,
order_id varchar(32) NOT NULL,
create_time datetime DEFAULT NULL,
primary key(id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
dbpartition by STR_HASH(`order_id`, 2, 7)
tbpartition by STR_HASH(`order_id`, 2, 7) tbpartitions 2;
  • 假设需要截取order_id的前5个字符串作为子串来计算分库分表路由,则您可以使用如SQL进行建表。
create table test_str_hash_tb (    
id int NOT NULL AUTO_INCREMENT,
order_id varchar(32) NOT NULL,
create_time datetime DEFAULT NULL,
primary key(id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
dbpartition by STR_HASH(`order_id`, 5, -1)
tbpartition by STR_HASH(`order_id`, 5, -1) tbpartitions 2;

常见问题

Q:dbpartition by STR_HASH(order\_id) dbpartition by HASH(order\_id)有什么区别?

A:两者虽然都是直接根据字符串取值做分库分表的哈希路由,但是两者的分库分表的路由算法实现不一样。前者支持用户建表时自行设定截取子串相关参数,且在根据字符串的哈希值计算分库分表路由时是基于UNI_HASH算法进行计算;而后者是只对字符串的哈希值做简单取模。

上一篇:HASH


相关文章
|
存储 监控 安全
智慧工地管理平台的技术架构和工作原理
智慧工地管理平台是将互联网+的理念和技术引入建筑工地,从施工现场源头抓起,最大程度的收集人员、安全、环境、材料等关键业务数据,依托物联网、互联网,建立云端大数据管理平台,形成“端+云+大数据”的业务体系和新的管理模式,打通从一线操作与远程监管的数据链条,实现劳务、安全、环境、材料各业务环节的智能化、互联网化管理,提升建筑工地的精益生产管理水平。实现“互联网+”与建筑工地的跨界融合,促进行业转型升级。
856 1
EMQ
|
存储 人工智能 边缘计算
云边协同架构助力智能工厂视觉 AI 缺陷检测应用构建
打破检测系统和产线自动化设备之间的信息孤岛,构建数据高速通道,为视觉AI缺陷检测算法模型提供数据支撑,实现工厂生产智慧优化。
EMQ
988 1
云边协同架构助力智能工厂视觉 AI 缺陷检测应用构建
|
存储 监控 容灾
微信技术总监谈架构:微信之道——大道至简(演讲全文)
在技术架构上,微信是如何做到的?日前,在腾讯大讲堂在中山大学校园宣讲活动上,腾讯广研助理总经理、微信技术总监周颢在两小时的演讲中揭开了微信背后的秘密。 周颢把微信的成功归结于腾讯式的“三位一体”策略:即产品精准、项目敏捷、技术支撑。微信的成功是在三个方面的结合比较好,能够超出绝大多数同行或对手,使得微信走到比较前的位置。所谓产品精准,通俗的讲就是在恰当的时机做了恰当的事,推出了重量级功能,在合适的时间以最符合大家需求的方式推出去。他认为在整个微信的成功中,产品精准占了很大一部分权重。
465 1
微信技术总监谈架构:微信之道——大道至简(演讲全文)
|
存储 关系型数据库 MySQL
Python写入文件内容:从入门到精通
本文详细介绍了使用Python进行文件写入的基本方法及高级技巧。从基础语法入手,讲解了如何使用`open()`函数的不同模式(如`'w'`和`'a'`)来创建或修改文件,并通过具体示例演示了`write()`和`writelines()`方法的应用。进一步探讨了利用CSV模块处理复杂数据结构的写入操作,以及在实际项目中如何批量导出数据库记录到CSV文件。最后,文章还讨论了在处理大数据集和云存储时的注意事项与优化方案。
260 4
|
人工智能 搜索推荐 API
langchain 入门指南 - 让 AI 从互联网获取信息
langchain 入门指南 - 让 AI 从互联网获取信息
397 1
|
架构师 数据安全/隐私保护
深入探索领域分析:从问题空间到核心域
深入探索领域分析:从问题空间到核心域
|
弹性计算 分布式计算 运维
迟来的EMR Serverless Spark评测报告
本文是一篇关于阿里云EMR Serverless Spark产品评测的文章,作者分享了使用体验和理解。EMR Serverless Spark是阿里云提供的全托管、一站式的Spark数据计算平台,简化了大数据处理流程,让用户专注于数据分析。文章提到了产品的主要优势,如快速启动、弹性伸缩、高资源利用率和低成本。
520 8
|
数据挖掘
提高调查有效性:问卷设计技巧与常见错误避免
设计合格的调查问卷需明确目标、构建清晰结构、编写简明问题并预测试与修改。目标决定数据收集的方向,结构保证逻辑连贯,问题应避免引导性,使用通俗语言。预测试能优化问卷,数据分析则提炼出有价值信息,支持决策。注意问题类型的选择,如封闭式和开放式,确保数据的有效收集。
1265 4
|
监控 Java
JAVA性能优化- IntelliJ插件:java内存分析工具(JProfiler)
JAVA性能优化- IntelliJ插件:java内存分析工具(JProfiler)
437 0
|
存储 机器学习/深度学习 人工智能
5个优质免费自然语言处理学习资源 | 语言技术导航
5个优质免费自然语言处理学习资源 | 语言技术导航