本地TopN索引

本地TopN索引是在本地索引的基础上,对每个索引条目中的数据记录Key列表按指定字段进行排序,并且保留TopN个记录Key。本地TopN索引本质也是本地索引,所以也可以直接当本地索引使用。

支持按多个Value字段进行排序,各个排序字段的排序类型(升序/降序)可以不同。

支持在1张表中创建多个本地TopN索引。

1. 索引特点

TopN索引的特点主要有两点:

  • TopN也是一种本地索引,与普通本地索引一样,都是对单个数据分片内的数据的局部索引,也是在表定义文件中进行定义;

  • TopN索引条件中的数据记录Key列表按指定字段进行了排序,并且只保留TopN个。

2. 使用场景

TopN索引主要用于类似于排行榜(N <= 10000)的场景。如按积分排名的场景。

3. 使用索引

3.1. 定义索引

在表定义文件中声明本地TopN索引,与声明其它本地索引的方式类似。同样是在index标签中指定索引名称,索引字段等属性。不同的是需要在表的customattr2扩展属性中通过OrderBy, Limit等属性指定排序字段和排序顺序类型、保留的row_key个数等。

以排行榜场景为例。

表定义样例:

表定义说明:

  • rank_name为榜单名称字段,要求必须将该字段设置为分表因子和本地TopN索引字段,保证同一榜单的数据存储在同一个节点上,同时,访问时也将根据该字段值定位到对应的TopN索引条目;

  • uid和area_id为数据的Key字段,与rank_name一同构成表的Primary Key;

  • score1为第1个排序字段,数据类型仅限于整数和浮点数;

  • score2为第2个排序字段;

  • uname为第1个数据的Value字段,可以定义多个Value字段,数据类型不限;

  • umail为第2个数据的Value字段;

  • index标签定义本地TopN索引,指定索引名称和索引字段,与普通的本地索引定义是相同的,要求也是相同的。如果要将一个本地索引声明成TopN索引,需要在表的customattr2扩展属性中指定索引的排序字段、排序顺序类型和榜单长度等关键信息,见示例。

  • IndexName:要声明为TopN索引的索引名称,必选;

  • OrderBy:排序字段名称及类型列表,必选;

  • Limit:榜单长度限制,取值范围为(0, 10000],必选;

  • AutoDeleteDataRecord:为true表示,当数据被“挤”出所有榜单时,数据库系统会同步删除该条数据,否则的话,数据将会保留,只在索引删除对应的row_key,可选,默认为false。

特别说明:

包含本地TopN索引定义的表中,系统内置了一个字段(__index__),用于存储每条数据在索引中的序号。针对该字段的限制有:

  1. 该字段不需要在表定义中定义,也不允许在表定义中定义同名的字段;

  2. 该字段可以直接查询,但不可以直接更新。

3.2. 查询索引

查询要命中本地TopN索引,必须严格满足以下几个条件:

  1. 查询语句必须包含WHERE子句,且过滤条件符合本地索引PartKey的要求,即形如:key1=value1 AND key2=value2 AND ...。

  2. 查询语句必须包含ORDER BY子句,且排序字段顺序和排序类型要与本地TopN索引定义中的排序字段定义保持一致。如果想要查询结果倒序返回,需要在外层再嵌套一层查询,并且外查询的ORDRE BY中排序字段顺序要与本地TopN索引定义中的排序字段一致,但排序类型全部完全相反,详见下一章节的样例5.5

  3. 查询语句必须包含LIMIT子句,且LIMIT值必须小于或者等于本地TopN索引定义中的LIMIT值。

示例

假设表定义中定义2个本地TopN索引,分别如下:

  • index1:OrderBy=score1:DESC;Limit=1000

  • index2:OrderBy=score1:ASC,score2:DESC;Limit=100

那么针对不同的SQL语句,索引的命中情况如下:

SQL语句 索引命中情况
SELECT uid, uname FROM rank_table 未命中
SELECT uid, uname FROM rank_table WHERE rank_name='rank1' ORDER BY score1 ASC, score2 DESC LIMIT 10 index2
SELECT uid, uname FROM rank_table WHERE rank_name='rank1' ORDER BY score1 DESC, score2 DESC LIMIT 10 未命中
SELECT uid, uname FROM rank_table WHERE rank_name='rank1' ORDER BY score1 DESC 未命中
SELECT uid, uname FROM rank_table WHERE rank_name='rank1' ORDER BY score1 DESC LIMIT 10 index1
SELECT uid, uname FROM rank_table WHERE rank_name='rank1' ORDER BY score1 DESC LIMIT 1001 未命中
SELECT uid, uname FROM rank_table WHERE rank_name='rank1' ORDER BY score2 DESC LIMIT 10 未命中

3.3. 典型查询场景

3.3.1 查询指定索引条目中的TopN个数据

SELECT uid, uname FROM rank_table WHERE rank_name='rank1' ORDER BY score1 DESC LIMIT 10;
SELECT uid, uname FROM rank_table WHERE rank_name='rank1' ORDER BY score1 DESC, score2 ASC LIMIT 10;

说明:当LIMIT大于索引条目中实际row_key的个数时,返回的数据行数以实际row_key个数为准。

3.3.2 查询指定数据在指定索引条目中的序号

SELECT uid, __index__ FROM (SELECT * FROM rank_table WHERE rank_name='rank1' ORDER BY score1 DESC LIMIT 10) WHERE uid=0;

说明:_ index\_为内置字段,每条数据在不同的TopN索引中的__index__有可能是不同的,同时随着数据的更新,这个值也会变化。当查询命中了某个TopN索引,且数据在TopN索引中时,__index__为一个正整数(从0开始计数);否则,__index__的值固定为-1。

3.3.3 查询指定索引条目中指定范围内的数据

SELECT uid, score1, uname FROM (SELECT * FROM rank_table WHERE rank_name='rank1' ORDER BY score1 DESC LIMIT 1000) WHERE 10 < score1 AND score1 < 20;
SELECT uid, score1, uname FROM (SELECT * FROM rank_table WHERE rank_name='rank1' ORDER BY score1 DESC LIMIT 1000) WHERE 10 < __index__ AND __index__ < 20;

3.3.4 查询指定索引条目中的数据个数

SELECT count(1) FROM (SELECT * FROM rank_table WHERE rank_name='rank1' ORDER BY score1 DESC, score2 ASC LIMIT 10);

说明:返回指定索引条目中实际数据个数,值小于或等于索引条目的最大长度限制。

3.3.5 查询指定索引条目中的数据,并反转顺序返回

SELECT uid, uname FROM (SELECT * FROM rank_table WHERE rank_name='rank1' ORDER BY score1 DESC LIMIT 10) WHERE rank_name='rank1' ORDER BY score1 ASC;

说明:当TopN索引包含多个排序字段时,如果要结果集整体倒序输出,则外查询的Order By里所有排序字段的排序类型要全部与TopN索引中的排序类型相关,不允许出现部分相关的情况。

3.3.6 遍历指定索引条目中的数据

SELECT uid, score1, uname FROM rank_table WHERE rank_name='rank1' ORDER BY score1 DESC, score2 ASC LIMIT 1000;

4. 使用限制

  • 暂时只支持在TDR Generic表上定义本地TopN索引。

  • 当前只支持通过MySQL协议兼容接口访问TopN索引或使用3.55.0以上版本的SDK访问使用(使用前请确认服务端需要升级到3.64.0以后的版本)。

  • 表的单个主键字段的size不能超过32个字节,建表后主键字段的size不允许变更.

  • 本地TopN索引"N"的最大值为10000。

  • 排序字段的数据类型仅限于整数型和浮点型。

  • 排序字段个数不允许超过8个。

  • 删除当前在本地TopN索引中的数据后,索引中空出的位置不会自动替补。比如索引中记录了成绩排在前100名的玩家,删除第50名玩家之后,第101名玩家并不会自动替补到索引中。

  • 向本地TopN索引中插入新数据之后,之前排在TopN最末位的就会被”挤出“索引,此时,默认情况下,数据库系统并不会同步删除这条被”挤出“的数据,数据仍然可以通过GET等其它方式查询到。如果需要进行同步删除,则需要在本地TopN索引定义中指定AutoDeleteDataRecord属性为true。

5. 注意事项

<待补充>

results matching ""

    No results matching ""