【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級存儲、毫秒級時延、無損水準擴充和複雜資料結構等特性。同時具備豐富的生态、便捷的遷移、極低的運維成本和五個九高可用等特點。客戶覆寫遊戲、網際網路、政務、金融、制造和物聯網等領域。