- 1.3 SDS服务简介
- 1.3.1 帐号注册
- 1.3.2 数据模型
- 1.3.3 二级索引
- 1.3.4 支持的操作
- 1.3.5 配额说明
- 1.3.6 计量计费
- 1.3.7 AutoScaling
- 1.3.8 Stream
- 1.3.9 Recovery
- 1.3.10 冷备
- 1.3.11 权限模型
- 1.3.12 集群信息
- 1.3.13 Client配置
- 1.3.14 多语言SDK
- 1.3.15 离线分析
- 1.3.16 监控统计
- 1.3.17 数据加密
- 1.3.18 示例
- 1.4 API
- 1.4.1 创建表
- 1.4.2 修改表
- 1.4.3 克隆表
- 1.4.4 禁用表
- 1.4.5 启用表
- 1.4.6 删除表
- 1.4.7 描述表
- 1.4.8 获得表的状态
- 1.4.9 列出所有表
- 1.5 API
- 1.5.1 写记录
- 1.5.2 读记录
- 1.5.3 删除记录
- 1.5.4 自增操作
- 1.5.5 批量操作
- 1.5.6 带条件的批量写操作
- 1.5.7 允许部分执行的批量操作
- 1.5.8 扫描记录
- 1.5.9 事务操作
- 1.6 FAQ
- 1.6.1 认证授权
- 1.6.2 数据模型
- 1.6.3 旧版帐号迁移到新版
- 1.6.4 RESOURCE_NOT_FOUND异常
- 1.6.5 常见错误
1.5.8 扫描记录
ScanResult scan(ScanRequest request)
功能
扫描操作,每个扫描过的记录消耗1个读配额(即使不满足过滤条件),每个Lazy二级索引需要1个额外读配额
方法参数
request : ScanRequest : required
ScanRequest包括以下部分
1.tableName : String : required
指定扫描的表名
2.indexName :String : optional
指定扫描的二级索引名,如果不指定,即扫描主记录
3.startKey : Map< String, Datum > :optional
查询范围开始,包含startKey,如果startKey不是完整键,而是部分key的前缀,则实际查询的startKey为{startKey, 最小可能的后缀}补全形式
4.stopKey : Map< String, Datum > :optional
查询范围结束,不包含stopKey,如果stopKey不是完整键,而是部分key的前缀,则实际查询的stopKey为{stopKey, 最大可能的后缀}补全形式
5.attributes : List< String > :optional
需要返回的属性列表,不指定表示返回所有属性
6.condition : String : optional
类SQL WHERE语句的查询条件。 注意:与SQL不同,此条件仅作为过滤条件,不影响具体查询计划(index, startKey, endKey),进行范围查询时需要显示设置index和startKey以及endKey。每个扫描的记录均计入读配额,即使不满足查询条件。尽量避免使用条件过滤,尤其是当过滤掉的记录占一半以上时,强烈不建议使用。
7.limit :int : optinal
返回记录的最大数目,返回数目可能小于此值(如超出表的读配额时), 默认为10, 范围(0, 1000]
8.reverse : boolean : optional
是否进行逆序扫描,进行逆序扫描时startKey应大于endKey
注意:逆序查询效率较低,谨慎使用,建议设置对应的Key为逆序存储
9.inGlobalOrder :boolean :optional
是否全局有序扫描,对于设置了实体组键且开启了哈希的表,需要设置该值为true才能保证结果有序
10.action :ScanAction : optional
scan时的连带操作,包括COUNT,DELETE和UPDATE, 类似SQL的select count(*) / update XXX / delete XXX from table where XXX 语义
方法返回值
scanResult : ScanResult
scanResult包括以下内容
1.records : List< Map< String,Datum > >
扫描到的记录
2.nextStartKey : Map< String,Datum >
下一个需要扫描的记录主键,NULL表示达到制定的结束位置
异常错误码
INTERNAL_ERROR(1) : 服务器异常
ACCESS_DENIED(4) : 用户对该表没有读权限
VALIDATION_FAILED(5): 参数设置错误
THROUGHPUT_EXCEED(8): 当前读写速度已超过该表的读写配额
RESOURCE_NOT_FOUND(9) : 所指定的表不存在
限制
limit 值的范围为 (0, 1000]
limit数值设置过大会对服务器造成过大的压力,但是如果limit设置过小会增加访问服务器的频率
注意
可以选择使用主键(indexName不指定表示通过主键查询) 和二级索引查询。扫描可以指定查询范围,不指定时表示全表扫描。 查询范围定义的区间是[startKey, stopKey), 即两者全部属性都指定且相同时 查询的范围为空。其中startKey和stopKey可以只指定主键或者对应索引的部分属性(必须为前缀),指定 前缀时,查询范围的区间为 [startKey前缀 + 后缀可能的最小值, stopKey前缀 + 后缀可能的最大值 + 1)。例如, startKey = {userId = "user1"}, stopKey = {userId = "user1"} 表示查询user1下的所有笔记
扫描操作还可以指定过滤条件,需要注意的是,被条件过滤掉的记录也要计算读配额(根据索引类型 记1个或2个读配额)。过滤条件的语法类似SQL的Where语句。需要注意,属性不存在表示值为null, 除isnull和notnull操作符之外的所有其他表达式和函数调用结果都为null,如果表达式最终的值为null,则表达式的计算结果为false。
如果定义了哈希分布,跨实体组进行扫描需要先分别确定在每个哈希桶中的范围分布,再分别对每个哈希桶进行局部扫描,最后对所有桶内扫描结果进行归并排序, 因此会 引入较大性能开销,建议谨慎使用。 注:这种场景建议用户采用结构化存储MapReduce API MapReduce分布式计算框架将上述步骤分布 到多台机器并行执行,从而极大提高扫描性能。
扫描的三种方式
scan
扫描获得指定的startKey到stopKey之间的数据, limit中设置的数值为返回的最大数据量
以下两种情况返回数据量不等于limit
- 用户读quota不足,发生throughput throttle
- 已经扫完了最后的数据
示例
$scan = new ScanRequest(array(
"tableName" => $tableName,
"indexName" => "mtime",
"startKey" => array(
"userId" => DatumUtil::datum("user1"),
),
"stopKey" => array(
"userId" => DatumUtil::datum("user1"),
),
"condition" => "title REGEXP '.*[0-5]' AND noteId > 5",
"attributes" => array("noteId", "title", "mtime"),
"limit" => 50 // 每次rpc返回的最大记录条数
));
$tableClient->scan($scan)
scanAll
scanAll是scan的一种实现,主要解决发生quota不足时返回不足limit的问题
只有一种情况返回数据量不足limit:
- 已经扫完了最后的数据
示例
$scan = new ScanRequest(array(
"tableName" => $tableName,
"indexName" => "mtime",
"startKey" => array(
"userId" => DatumUtil::datum("user1"),
),
"stopKey" => array(
"userId" => DatumUtil::datum("user1"),
),
"condition" => "title REGEXP '.*[0-5]' AND noteId > 5",
"attributes" => array("noteId", "title", "mtime"),
"limit" => 50 // 每次rpc返回的最大记录条数
));
$tableClient->scanAll($scan)
TableScanner
TableScanner是一种机制,一般情况下scan结束后需要判断scan返回的NextStartKey进行下一次scan,而TableScanner则可以在设置好scan参数后不断调用next获取后续的数据.
示例
$scan = new ScanRequest(array(
"tableName" => $tableName,
"indexName" => "mtime",
"startKey" => array(
"userId" => DatumUtil::datum("user1"),
),
"stopKey" => array(
"userId" => DatumUtil::datum("user1"),
),
"condition" => "title REGEXP '.*[0-5]' AND noteId > 5",
"attributes" => array("noteId", "title", "mtime"),
"limit" => 50 // 每次rpc返回的最大记录条数
));
$scanner = new TableScanner($tableClient, $scan);
foreach ($scanner->iterator() as $k => $v) {
echo "$k: " . DatumUtil::value($v['noteId'])
. " [" . DatumUtil::value($v['title']) . "] "
. DatumUtil::value($v['mtime']) . "\n";
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论