1.3.3 二级索引
SDS 的二级索引支持局部二级索引与及全局二级索引,目前这两种索引都是强一致的索引
局部二级索引
使用局部二级索引必须要定义实体组键,由一个到多个表属性组成, 索引分为Lazy,Eager和Immutable三种类别
Lazy索引 -写入时同时写入索引记录,但是不会立马删除已无效的索引记录,需要等到读取时,读到无效的索引记录再删除,写效率高而读效率较低,所以此类型索引适合写多读少的场景,不支持投影属性和唯一索引。
Eager索引 -写入时同时写入索引记录,并且立马删除已无效的索引记录,在读取时,确保读到的索引记录都是有效的,写入效率较低而读效率高,所以此类性型的索引适合写少读多的场景,可以支持唯一索引(Unique Index),并且可以定义一组属性作为 投影(Projection),与索引存储在一起(可视为主记录中对应属性的一份拷贝,属性值保持强一致)。
Immutable索引 -此类索引适合不会覆盖写的数据,即写入后不会再修改(需要用户自己保证),由于不会覆盖写不会产生无效的索引记录,所以写效率和读效率都比较高,适合这种场景的表推荐使用此类型索引,此类型索引支持投影,但不支持唯一索引。
索引定义 LocalSecondaryIndexSpec
indexSchema : List< KeySpec >
指定对哪些属性建立索引, 与及作为索引记录键值时的编码方式(asc/desc)consistencyMode : SecondaryIndexConsistencyMode
, 定义索引类型, LAZY 、EAGER或IMMUTABLEprojections : List< String >
, 属性名列表,定义索引记录中包含主记录的哪些属性的拷贝,只有索引类型为EAGER或IMMUTABLE时才能设置unique : boolean
, 是否为唯一索引,索引类型为EAGER才能为true
读写索引的配额计算
各类型索引读写产生的额外quota计算详见配额说明
索引添加
可以在建表时添加局部二级索引,也可以对已存在的表添加局部二级索引,对已存在表添加索引只能添加类型为Eager的非唯一索引,且对添加索引前已存在的数据需要用重建索引的工具对表进行重建索引
局限
使用局部二级索引必须定义实体组键,索引记录只能索引同一个实体组键的记录,所以在用scan读取数据时starKey和stopKey必须是同一个实体组键内的,即指定所有实体组键属性的值,且相等。
全局二级索引
建立全局二级索引的表可已不定义实体组键,该索引被视为全局的是因为对索引可以查询整表的数据. 全局二级索引的索引数据和原数据物理上存在于不同的两个表,可以独立定义索引表的实体组键,主键, quota, 预分片等。
索引定义 GlobalSecondaryIndexSpec
indexEntityGroup : EntityGroupSpec
(可选) 索引的键值属性的一部分,该部分可以对索引表做hash,避免访问热点, 对于设置实体组键开启hash的,需要避免对索引表进行跨实体组键scanindexPrimaryKey : List< KeySpec >
(可选)索引的键值属性的一部分,在indexEntityGroup为空时该值不能为空, 主表中未被覆盖的rowkey属性,会在全局索引表中按序添加到主键projections : List< String > (可选)属性名列表,定义索引记录中包含主记录的哪些属性的拷贝,若为空,索引表只包含indexEntityGroup, indexPrimaryKey和原表的键值属性
consistencyLevel : ConsistencyLevel
(必须) 索引表和原表的数据一致性等级 STRONG/EVENTUAL/WEAK, 默认为STRONG,现在也暂时只支持STRONGunique : boolean
: (必须) 是否唯一索引,默认为非唯一索引,现在也只支持非唯一索引throughput : ProvisionThroughput
(必须) 索引表在主集群的读写配额slaveThroughput : ProvisionThroughput
(可选)索引表在备集群的读写配额,如果不设置,即和主集群的读写配额相等exceededThroughput : ProvisionThroughput
(可选) 索引表在主集群的最大可超发的读写配额,如果不设置,默认为主集群读写配额的1.5倍exceededSlaveThroughput : ProvisionThroughput
(可选) 索引表在备集群的最大可超发的读写配额,如果不设置,默认为备集群读写配额的1.5倍preSplits : int
: 仅支持Entity Group开启hash分布的索引表,范围是[ 1, 256 ]
读写索引的配额计算
对于带全局二级索引的表进行put/delete操作,需要消耗原表写入配额为写入的数据的容量单位+1个额外的容量单位, 如果涉及索引表的更新,还需要消耗原表读取旧记录的容量单位,更新索引时,需要消耗索引表索引数据占的容量单位 +1个额外的容量单位,
scan/get,按照实际读取数据所占的容量单位计算,scan时如果是查询索引数据,消耗的是索引表的配额,如果是查询原表,消耗的是原表的配额
局限
一个表不能同时设置局部二级索引和全局二级索引; 查询全局二级索引只能读取投影属性
区别
在确定要使用的索引类型时,应考虑应用程序的要求。下表是局部二级索引与全局二级索引的主要区别
性能 | 局部二级索引 | 全局二级索引 |
---|---|---|
键值结构 | 必须和原表有同样的实体主键结构 | 可以独立定义索引表的实体组键和主键 |
在线索引操作 | 可以添加或删除局部二级索引, 也可以修改局部二级索引的类型,但只能从Immutable改成Eager | 不能添加/删除/修改全局二级索引 |
查询与实体组键 | 通过局部二级索引,只能查询同一个实体组键的数据 | 通过全局二级索引,可以查询整个原表的数据 |
读取一致性 | 强一致 | 暂时只支持强一致的,计划以后支持弱一致及最终一致 |
读写配额使用 | 局部二级索引的读写都占用原表的读写配额 | 全局二级索引的索引表的配额与原表的配额独立计算 |
投影属性 | 局部二级索引可以查询未被投影的属性 | 全局二级索引只能查询投影的属性,不会从原表读取其它非投影属性 |