写点什么

【深入理解 TcaplusDB 技术】理解 TcaplusDB 本地索引

作者:数据人er
  • 2022 年 5 月 16 日
  • 本文字数:2830 字

    阅读完需:约 9 分钟

【深入理解TcaplusDB技术】理解TcaplusDB本地索引

【深入理解 TcaplusDB 技术】理解 TcaplusDB 本地索引

索引介绍

TcaplusDB 支持两种形式的索引:本地索引和全局索引。


  • 本地索引:基于 TcaplusDB 主键字段建立的索引,在建表时随表一起建立。

  • 全局索引:基于 TcaplusDB 表一级字段(包括主键字段和非主键字段)建立的索引。


通过本地索引和全局索引,用户可方便利用索引进行数据查询。优势:


  • 基于本地索引查询,可以满足用户通过部分主键字段进行索引查询

  • 基于全局索引,可以满足用户通过任意一级字段进行多种形式查询,如范围、模糊、聚合、分页等。

使用限制

本地索引使用限制

  • 本地索引一旦创建,无法在使用期间修改、删除、新增,随表删除而删除。

  • 本地索引只支持精确匹配,即在用本地索引字段作为查询条件时,只能精确匹配到具体值,不支持模糊、范围匹配。

全局索引使用限制

  • 全局索引只支持表一级字段,对于那些嵌套字段、数组列表类型字段不支持创建全局索引。

  • 全局索引只支持 Generic 类型表,对于 List 类型表不支持。

  • 全局索引目前支持在 tcaplus_client 工具、C++ SDK(TDR 协议表 &PB 协议表)、JDBC 以及 GO API 中使用。

  • 全局索引有部分 SQL 不支持,请参考本文末关于不支持 SQL 的描述

本地索引

特点

  • 本地索引是实时索引,当插入或者删除数据时,会同时更新索引数据;

  • 本地索引的字段必须包含在主键字段中,并且字段中还必须包含分片字段,因此,查询时最终只会落到一个数据分片上进行查询;

  • 本地索引只支持等值查询;

  • 一个表可以建立多个本地索引,查询时必须包含某一个本地索引的全部字段;

  • 目前只有 generic 表支持本地索引;

创建

本地索引是在建立表的时候,在表定义中申明的,并且一旦表创建后,就不能再增加、修改和删除本地索引了,删除表的时候,本地索引会一并删除;

tdr 表定义本地索引

示例如下:


<?xml version="1.0" encoding="GBK" standalone="yes" ?> <metalib name="tcaplus_tb" tagsetversion="1" version="1"> <struct name="PLAYERONLINECNT" version="1" primarykey="TimeStamp,GameSvrID,GameAppID" splittablekey="TimeStamp">    <entry name="TimeStamp"           type="uint32"     desc="单位为分钟" />    <entry name="GameSvrID"         type="string"     size="64" />    <entry name="GameAppID"         type="string"     size="64" desc="gameapp id" />    <entry name="OnlineCntIOS"      type="uint32"     defaultvalue="0" desc="ios在线人数" />    <entry name="OnlineCntAndroid"  type="uint32"     defaultvalue="0" desc="android在线人数" />    <entry name="BinaryLen"         type="smalluint" defaultvalue="1" desc="数据来源数据长度;长度为0时,忽略来源检查"/>    <entry name="binary"            type="tinyint"     desc="二进制" count= "1000" refer="BinaryLen" />    <entry name="binary2"           type="tinyint"     desc="二进制2" count= "1000" refer="BinaryLen" />    <entry name="strstr"            type="string"     size="64" desc="字符串"/>    <index name="index_1"  column="TimeStamp"/>    <index name="index_2"  column="TimeStamp, GameSvrID"/>    <index name="index_3"  column="TimeStamp, GameAppID"/></struct> </metalib>
复制代码


​ 其中,index 的那几项就是定义的本地索引,上面表中定义了 3 个本地索引(index_1, index_2, index_3),索引的名字可以任意的字符串,column 是该索引所包含的字段,多个字段之间通过逗号隔开。 索引约束:


  • 本地索引必须包含分片因子, 如上所示 TimeStamp 字段必须包含在每个主键索引中;

  • 本地索引中的字段都必须属于主键字段,因此,对 GameSvrID 和 GameAppID 建立索引是不允许的;

  • 对其它非主键字段建立本地索引也是不允许的。

pb 表定义本地索引

示例如下:


syntax = "proto3";                      // Specify the version of the protocol buffers language  import "tcaplusservice.optionv1.proto"; // Use the public definitions of TcaplusDB by importing them.  message game_players {  // Define a TcaplusDB table with message         // Specify the primary keys with the option tcaplusservice.tcaplus_primary_key        // The primary key of a TcaplusDB table has a limit of 4 fields    option(tcaplusservice.tcaplus_primary_key) = "player_id, player_name, player_email";     // Specify the primary key indexes with the option tcaplusservice.tcaplus_index    option(tcaplusservice.tcaplus_index) = "index_1(player_id, player_name)";    option(tcaplusservice.tcaplus_index) = "index_2(player_id, player_email)";      // Value Types supported by TcaplusDB    // int32, int64, uint32, uint64, sint32, sint64, bool, fixed64, sfixed64, double, fixed32, sfixed32, float, string, bytes    // Nested Types Message     // primary key fields    int64 player_id = 1;     string player_name = 2;    string player_email = 3;      // Ordinary fields    int32 game_server_id = 4;    repeated string login_timestamp = 5;    repeated string logout_timestamp = 6;    bool is_online = 7;     payment pay = 8;}  message payment {             int64 pay_id = 1;        uint64 amount = 2;    int64 method = 3; }
复制代码


​ 其中,**option(tcaplusservice.tcaplus_index)**就是本地索引的定义方式,index_1(player_id, player_name)中的 index_1 是索引名,player_id 和 player_name 是索引字段;

查询

本地索引只支持等值查询,也就说,使用本地索引查询时,需要将本地索引中定义的字段全部都给值,比如定义了本地索引,包含字段为 key1, key2,那么使用该索引进行查询时,就必须把 key1 和 key2 的值给出来才可以,并且是 key1=XXX and key2=XXX 的方式进行查询;


在 tcaplus 中,对应的是 GetByPartKey 请求,只有该请求是利用本地索引进行查询的;


由于本地索引查询时,可能会返回非常多的数据,此时,tcaplus 会进行分包返回的,如果业务侧收包速度低于 tcaplus 返回响应包的速度,那么就可能导致 tcaplus 出现因为网络缓存区满而丢包的情况,一般建议是使用本地索引查询时,利用 limit 和 offset 的方式来分多次请求数据,特别是当数据量很大时;

注意事项

假设本地索引包含的字段为 key1, key2,如果出现 key1=XXX and key2=XXX 的记录数非常多时,当进行这个条件的本地索引查询时,就很容易出现性能问题,需要尽量避免,当然,目前 tcaplus 是没有限制记录数个数的。





TcaplusDB 是腾讯出品的分布式 NoSQL 数据库,存储和调度的代码完全自研。具备缓存+落地融合架构、PB 级存储、毫秒级时延、无损水平扩展和复杂数据结构等特性。同时具备丰富的生态、便捷的迁移、极低的运维成本和五个九高可用等特点。客户覆盖游戏、互联网、政务、金融、制造和物联网等领域。

用户头像

数据人er

关注

还未添加个人签名 2021.03.09 加入

还未添加个人简介

评论

发布
暂无评论
【深入理解TcaplusDB技术】理解TcaplusDB本地索引_数据库_数据人er_InfoQ写作社区