跳到主要内容

统一查询分库分表

NineData 表分组查询功能支持您通过 SQL 窗口对多个分库分表进行统一查询,很大程度上简化了分库分表情况下,数据查询的复杂度,提高查询效率。

背景信息

在企业用户规模达到一定程度后,分库分表成为一种常见的数据库架构选择。在这种情况下,查询和维护数据需要高效的解决方案,以避免手动逐一查询、变更和汇总多个分库和分表的繁琐操作。

库分组变更功能的上线在一定程度上解决了分库分表的变更问题,并在很多企业中得到了很好的验证和使用。然而,对于分库分表的查询需求,企业希望能够像操作单表一样便捷,这种操作方式可以满足更多数据处理场景的需求。

前提条件

  • 已创建或加入组织,并且该组织已开通,同时请确保您的包年包月订阅未过期。更多信息,请参见管理组织
  • 当前账号已切换到目标组织。更多信息,请参见切换到组织

创建库分组

该步骤用于将多个需要进行查询的数据库分到同一个分组中,以便后续进行统一查询操作。一个查询 SQL 语句将在同个库分组中的所有库中执行。

  1. 登录 NineData 控制台

  2. 在左侧导航栏,单击>

  3. 单击页签,单击页面中的>目标数据源

  4. 根据下表配置表单,并单击

    参数
    说明
    输入库分组的名称,仅支持英文字符、数字和下划线,以英文字符开头。为了方便后续使用和管理,请尽量使用有意义的名称。
    (可选)输入针对该库分组的业务描述。
    选择您的业务所属的环境名称,您将根据该环境筛选数据源。
    单击,添加数据源。
    • :选择需要加入到分组中的数据源,支持多选、全选和反选操作,同时支持输入数据源名称进行搜索。
    • :输入库表达式,系统将根据您提供的表达式,自动遍历并提取目标数据源中所有符合表达式的库。表达式的语法请参见本文附录
    单击后,如果您配置了,则系统会自动拉取符合条件的库,如果还需要选择其他库,可以单击右侧库的区域手动选择。
关于库分组的规范与流程

库分组创建完毕后,默认使用所属环境中配置的 SQL 开发规范以及审批流程,您可以根据业务需求进行更改,更多信息,请参见修改库分组的 SQL 开发规范和审批流程

创建表分组

相较于库分组,表分组用于更细粒度的分表配置,一个查询 SQL 语句将在同个表分组中的所有表中统一执行。如需创建表分组,必须已经创建库分组。

  1. 登录 NineData 控制台

  2. 在左侧导航栏,单击>

  3. 单击页签,单击目标库分组名称,或单击该库分组右侧列的more>

  4. 页面,单击

  5. 根据下表配置表单,并单击

    参数
    说明
    输入表分组的名称,仅支持英文字符、数字和下划线,以英文字符开头。为了方便后续使用和管理,请尽量使用有意义的名称。
    支持两种。
    选择时需要配置,输入表达式并单击后,系统将根据您提供的表达式,自动遍历并提取目标库中所有符合要求的表。表达式的语法请参见本文附录
    (可选)选择时可配置,根据您应用中配置的路由算法配置该参数,可以根据路由快速解析需要访问的表,提高查询效率。
    选择时需要配置,单击,选择需要加入到分组中的数据源,支持多选、全选和反选操作,同时支持输入数据源名称进行搜索,单击后,还需要选择具体的库和表,根据数据源不同,可能还需要选择具体的 Schema。
    提示

    如需通过快速路由至查询条件所在的表,实现以最快的速度获取查询结果,需要同时满足如下三个条件,如果不满足其中之一,则该查询将遍历所有分库分表进行查询。

    • 表分组是通过表达式创建的,并非手动选择。
    • 在上述表分组创建流程中正确配置了,且该算法必须和您应用中配置的路由算法一致。
    • 查询 SQL 的 WHERE 条件中,该路由字段为等值查询条件。

修改库分组的 SQL 开发规范和审批流程

用户在对目标表分组进行 SQL 查询时,可能会存在使用不规范 SQL 语句的情况,例如慢 SQL 等,这将导致数据库的性能受到严重影响。为解决这个问题,您可以为目标库分组配置 SQL 开发规范,作为系统自动审核用户 SQL 的依据,在检测到用户 SQL 不符合规范时,将会自动进行拦截。

  1. 登录 NineData 控制台

  2. 在左侧导航栏,单击>

  3. 页面,单击 页签,然后单击目标库分组右侧列的

  4. 窗口中,将规范流程下左侧的勾去掉,然后选择您需要的规范和流程,单击

    提示

    重新选中即可恢复成默认配置。

执行分库分表查询

实际对库表分组执行查询的操作是通过 SQL 窗口执行的,您可以在 SQL 窗口中直接通过 SQL 查询语句对表分组进行查询。

操作步骤

  1. 登录 NineData 控制台

  2. 在左侧导航栏单击 >,随便选一个数据源进入。

    提示

    如果之前登录过数据源且没有关闭,则会自动进入该数据源页面。

  3. 在页面左上角,单击当前数据源名称右侧的add_datasource。在弹出的窗口中,单击下方左侧下拉框,选择,然后单击右侧下拉框,选择目标需要查询的库分组。

  4. 您现在可以通过 SQL 窗口对目标库分组进行 SQL 查询。关于 SQL 窗口的使用方法,请参见 SQL 窗口

附录 1:分组表达式语法说明

NineData 支持通过表达式自动添加名称连续的库表到分组中,表达式的语法说明如下。

  • <dbname><tablename>:表示库名和表名。
    • <prefix>:表示库名或表名的前缀。
    • <suffix>:表示库名或表名的后缀。
  • <expression>:具体的表达式,包含如下规则:
    • <range>:表示范围,用英文横杠(-)连接,例如 1-9
    • <steps>:表示步长,和 <range> 配合使用,语法为 <range>:<steps>,即从 <range> 的起始位置到结束位置之间每隔多少个元素命中一次。例如 0-8:2,则命中 0、2、4、6、8
    • <enumeration>:表示枚举数字,每个数字之间用英文逗号(,)分隔。例如 1,3,5
  • <delimiter>:库名和表名之间的分隔符,用英文点号(.)表示,表示从属关系,例如 dbname.tablename
语法说明示例
<prefix>[<range>]<prefix> 为库名或表名前缀,<range> 为库名或表名后缀数字的范围,表示按照自然排序顺序添加对应的库或表。user_[0-9]:将名为 user_0、user_1、...、user_9 的 10 张表添加到表分组。
<prefix>[<range>:<steps>]<prefix> 为库名或表名前缀,<range> 为库名或表名后缀数字的范围,<steps> 为步长,即从 <range> 的起始位置到结束位置之间每隔多少个元素拉取一次。user_[0-9:3]:将名为 user_0、user_3、user_6、user_9 的 4 张表添加到表分组。
<prefix>[<expression>]<suffix>通常用于库表名编号位于名称中间的情况。user_[0-1]_sample:将名为 user_0_sample、user_1_sample 的 2 张表添加到表分组。
<prefix>[<expression>][<expression>]用于库名或表名中有多个编号的情况。user_[0-2]_[0-2]:将名为 user_0_0、user_0_1、user_0_2、user_1_0、user_1_1、...、user_2_2 的 9 张表添加到表分组。
<dbname_prefix>[<expression>].<tablename>用于多个库中都有单个相同表名的情况。db_[0-2].user:将名为 db_0、db_1、db_2 库下的名为 user 的表都添加到表分组。
<dbname_prefix>[<expression>].<tablename_prefix>[<expression>]用于多个不同的表分别存储于多个不同库中的情况。db_[0-2].user_[0-5]:将分别存储于 db_0 到 db_2 中的 user_0 到 user_5 的 6 张表添加到表分组。
<prefix>[<enumeration>]用于枚举多个库或表。user_[1,3,5]:将名为 user_1、user_3、user_5 的 3 张表添加到表分组。
<dbname_prefix>[<expression>].<tablename_prefix>[[<expression>]]用于多个库中都有多个相同表名的情况。
  • db_[0-2].user_[[0-2]]:将名为 db_0、db_1、db_2 库下的名为 user_0、user_1、user_2 的共计 9 个表都添加到表分组。
  • db_[0-2].user_[[0,2,3]]:将名为 db_0、db_1、db_2 库下的名为 user_0、user_2、user_3 的共计 9 个表都添加到表分组。
  • db_0.user_[0-2],db_1.user_[0-2]:将名为 db_0、db_1 库下的名为 user_0、user_1、user_2 的共计 6 个表都添加到表分组。

附录 2:路由算法说明

路由算法的主要功能是自动完成数据路由,路由算法配置中,目标分库与分表通过以下表达式定义:

'<dbname_expression>''.<tablename_expression>'
  • <dbname_expression>:分库名表达式,格式:'<dbname_prefix>'+(<expression>)+'<dbname_suffix>'

    • '<dbname_prefix>':分库名前缀,例如 'logical_db_0'
    • (<expression>):分库名组合的动态数字部分,例如 #user_id#%4。假设 user_id 列的值为 1,除以 4 取余的结果就是 1,则结合分库名前缀即为 logical_db_01。NineData 规定在路由算法中的字段名前后使用 # 进行标识,方便解析。
    • '<dbname_suffix>':分库名后缀,根据实际情况配置,可为空。例如 '_bak'。则组合后的分库名为 logical_db_01_bak

    示例:假设通过 #user_id#%4 计算的结果为 0,则路由到对应分库的 <dbname_expression> 写法如下。

    需路由的分库名称<dbname_expression>写法
    logical_db_01'logical_db_0'+(#user_id#%4+1)
    logical_db_01_bak'logical_db_0'+(#user_id#%4+1)+'_bak'
    logical_db_00'logical_db_0'+(#user_id#%4)
    logical_db_1'logicaldb'+(#user_id#%4+1)
  • .<tablename_expression>:分表名表达式,格式:'.<tablename_prefix>'+(<expression>)+'<tablename_suffix>'

    • '.<tablename_prefix>':分表名前缀,例如 '.test_time_0'。点(.)代表该表名隶属于前面的库。
    • (<expression>):分表名组合的动态数字部分,例如 #user_id#%4。假设 user_id 列的值为 1,除以 4 取余的结果就是 1,则结合分表名前缀即为 test_time_01。NineData 规定在路由算法中的字段名前后使用 # 进行标识,方便解析。
    • '<tablename_suffix>':分库名后缀,根据实际情况配置,可为空。例如 '_bak'。则组合后的分表名为 .test_time_01_bak

    示例:假设通过 #user_id#%4 计算的结果为 0,则路由到对应分表的 .<tablename_expression> 写法如下。

    需路由的分表名称<dbname_expression>写法
    test_time_01'.test_time_0'+(#user_id#%4+1)
    test_time_01_bak'.test_time_0'+(#user_id#%4+1)+'_bak'
    test_time_00'.test_time_0'+(#user_id#%4)
    test_time_1'.testtime'+(#user_id#%4+1)

结合上述的例子,如果 user_id 列的值为 0,那下述路由算法将路由至 logical_db_01 分库下的 test_time_01 分表。

'logical_db_0'+(#user_id#%4+1)'.test_time_0'+(#user_id#%4+1)