表格存储提供了GetRow接口用于读取单行数据以及BatchGetRow、GetRange等接口用于读取多行数据。
如果需要了解表格存储各场景的应用案例,请参见快速玩转Tablestore入门与实战。
查询方式
表格存储提供的数据读取接口包括GetRow、BatchGetRow和GetRange。读取数据时,请根据实际查询场景使用相应查询方式读取数据。
当要读取带有自增主键列的表数据时,请确保已获取到包含自增主键列值在内的完整主键。更多信息,请参见主键列自增。如果未记录自增主键列的值,您可以使用范围读取数据按照第一个主键列确定范围读取数据。
查询方式 | 说明 | 适用场景 |
调用GetRow接口读取一行数据。 | 适用于能确定完整主键且要读取行数较少的场景。 | |
调用BatchGetRow接口一次请求读取多行数据或者一次对多张表进行读取。 BatchGetRow操作由多个GetRow子操作组成,构造子操作的过程与使用GetRow接口时相同。 | 适用于能确定完整主键,且要读取行数较多或者要读取多个表中数据的场景。 | |
调用GetRange接口读取一个范围内的数据。 GetRange操作支持按照确定范围进行正序读取和逆序读取,可以设置要读取的行数。如果范围较大,已扫描的行数或者数据量超过一定限制,会停止扫描,并返回已获取的行和下一个主键信息。您可以根据返回的下一个主键信息,继续发起请求,获取范围内剩余的行。 | 适用于能确定完整主键范围或者主键前缀的场景。 重要 如果不能确定主键前缀,您也可以通过设置完整主键范围均为虚拟点INF_MIN和INF_MAX进行全表数据扫描,但是执行此操作会消耗较多计算资源,请谨慎使用。 |
前提条件
- 已初始化Client,详情请参见初始化。
- 已创建数据表并写入数据。
读取单行数据
调用GetRow接口读取一行数据。读取的结果可能有如下两种:
如果该行存在,则返回该行的各主键列以及属性列。
如果该行不存在,则返回中不包含行,并且不会报错。
接口
/**
* 读取一行数据。
* @api
* @param [] $request 请求参数。
* @return [] 请求返回。
* @throws OTSClientException 当参数检查出错或服务端返回校验出错时抛出异常。
* @throws OTSServerException 当OTS服务端返回错误时抛出异常。
*/
public function getRow(array $request);
请求参数
参数 | 说明 |
table_name | 数据表名称。 |
primary_key | 行的主键。主键包括主键列名、主键类型和主键值。 重要 设置的主键个数和类型必须和数据表的主键个数和类型一致。 |
max_versions | 最多读取的版本数。 重要 max_versions与time_range必须至少设置一个。
|
time_range | 读取版本号范围或特定版本号的数据。更多信息,请参见TimeRange。 重要 max_versions与time_range必须至少设置一个。
specific_time和 时间戳的单位为毫秒,最小值为0,最大值为 |
columns_to_get | 读取的列集合,列名可以是主键列或属性列。
说明
|
start_column | 读取的起始列,主要用于宽行读,返回的结果中包含当前起始列。 列的顺序按照列名的字典序排序。例如一张表有“a”、“b”、“c”三列,读取时设置start_column为“b”,则会从“b”列开始读,返回“b”、“c”两列。 |
end_column | 读取时的结束列,主要用于宽行读,返回的结果中不包含当前结束列。 列的顺序按照列名的字典序排序。例如一张表有“a”、“b”、“c”三列,读取时指定end_column为“b”,则读到“b”列时会结束,返回“a”列。 |
token | 宽行读取时下一次读取的起始位置,暂不可用。 |
column_filter | 使用过滤器,在服务端对读取结果再进行一次过滤,只返回符合过滤器中条件的数据行。更多信息,请参见过滤器。 说明 当columns_to_get和column_filter同时使用时,执行顺序是先获取columns_to_get指定的列,再在返回的列中进行条件过滤。 |
请求格式
$result = $client->getRow([
'table_name' => '<string>', //设置数据表名称。
'primary_key' => [ //设置主键。
['<string>', <PrimaryKeyValue>],
['<string>', <PrimaryKeyValue>],
['<string>', <PrimaryKeyValue>, <PrimaryKeyType>]
],
'max_versions' => <integer>,
'time_range' => [
'start_time' => <integer>,
'end_time' => <integer>,
'specific_time' => <integer>
],
'start_column' => '<string>',
'end_column' => '<string>',
'token' => '<string>',
'columns_to_get' => [
'<string>',
'<string>',
//...
],
'column_filter' => <ColumnCondition>
]);
响应参数
参数 | 说明 |
consumed | 本次操作消耗服务能力单元的值。 capacity_unit表示使用的读写能力单元。
|
primary_key | 主键的值,和请求时一致。 说明 如果该行不存在,则primary_key为空列表[]。 |
attribute_columns | 属性列的值。 说明 如果该行不存在,则attribute_columns为空列表[]。
|
next_token | 宽行读取时下一次读取的位置,暂不可用。 |
结果格式
[
'consumed' => [
'capacity_unit' => [
'read' => <integer>,
'write' => <integer>
]
],
'primary_key' => [
['<string>', <PrimaryKeyValue>],
['<string>', <PrimaryKeyValue>],
['<string>', <PrimaryKeyValue>, <PrimaryKeyType>]
],
'attribute_columns' => [
['<string>', <ColumnValue>, <ColumnType>, <integer>]
['<string>', <ColumnValue>, <ColumnType>, <integer>]
['<string>', <ColumnValue>, <ColumnType>, <integer>]
],
'next_token' => '<string>'
]
示例
读取最新版本数据和指定列
以下示例用于读取一行数据,设置读取最新版本的数据和读取的列。
$request = [
'table_name' => 'MyTable',
'primary_key' => [ //设置主键。
['PK0', 123],
['PK1', 'abc']
],
'max_versions' => 1, //设置读取最新版本。
'columns_to_get' => ['Col0'] //设置读取的列。
];
$response = $otsClient->getRow ($request);
使用过滤器读取数据
以下示例用于在读取一行数据时使用过滤器。
$request = [
'table_name' => 'MyTable',
'primary_key' => [ //设置主键。
['PK0', 123],
['PK1', 'abc']
],
'max_versions' => 1, //设置读取最新版本。
'column_filter' => [ //设置过滤器,当Col0列的值为0时,返回该行。
'column_name' => 'Col0',
'value' => 0,
'comparator' => ComparatorTypeConst::CONST_EQUAL,
'pass_if_missing' => false //如果Col0列不存在,则不返回该行。
]
];
$response = $otsClient->getRow ($request);
批量读取数据
调用BatchGetRow接口一次请求读取多行数据,也支持一次对多张表进行读取。BatchGetRow由多个GetRow子操作组成。构造子操作的过程与使用GetRow接口时相同。
BatchGetRow的各个子操作独立执行,表格存储会分别返回各个子操作的执行结果。
注意事项
由于批量读取可能存在部分行失败的情况,失败行的错误信息在返回的BatchGetRowResponse中,但并不抛出异常。因此调用BatchGetRow接口时,需要检查返回值,判断每行的状态是否成功。
批量读取的所有行采用相同的参数条件,例如
ColumnsToGet=[colA]
,表示要读取的所有行都只读取colA列。BatchGetRow操作单次支持读取的最大行数为100行。
接口
/**
* 读取指定的多行数据。
* 请注意BatchGetRow在部分行读取失败时,会在返回的$response中表示,而不是抛出异常。更多信息,请参见处理BatchGetRow的返回样例。
* @api
* @param [] $request 请求参数。
* @return [] 请求返回。
* @throws OTSClientException 当参数检查出错或服务端返回校验出错时。
* @throws OTSServerException 当OTS服务端返回错误时。
*/
public function batchGetRow(array $request);
请求参数
BatchGetRow和GetRow的区别如下:
增加了数据表的层级结构,可以一次读取多个数据表的数据。
tables以数据表为单位组织,后续为各个数据表的操作,设置了需要读取的行信息。
primary_key变为primary_keys,支持设置多行的主键,可以一次读取多行数据。
请求格式
$result = $client->batchGetRow([
'tables' => [ //设置数据表的层级结构。
[
'table_name' => '<string>', //设置数据表名称。
'primary_keys' => [ //设置主键。
[
['<string>', <PrimaryKeyValue>],
['<string>', <PrimaryKeyValue>],
['<string>', <PrimaryKeyValue>, <PrimaryKeyType>]
],
//其他主键。
]
'max_versions' => <integer>,
'time_range' => [
'start_time' => <integer>,
'end_time' => <integer>,
'specific_time' => <integer>
],
'start_column' => '<string>',
'end_column' => '<string>',
'token' => '<string>',
'columns_to_get' => [
'<string>',
'<string>',
//...
],
'column_filter' => <ColumnCondition>
],
//其他数据表。
]
]);
响应参数
tables以table为单位组织,和请求一一对应, 参数说明请参见下表。
参数 | 说明 |
table_name | 数据表名称。 |
is_ok | 该行操作是否成功。
|
error | 用于在操作失败时的响应消息中表示错误信息。
|
consumed | 本次操作消耗服务能力单元的值。 capacity_unit表示使用的读写能力单元。
|
primary_key | 主键的值,和请求时一致。 说明 如果该行不存在,则primary_key为空列表[]。 |
attribute_columns | 属性列的值。 说明 如果该行不存在,则attribute_columns为空列表[]。
|
next_token | 宽行读取时下一次读取的位置,暂不可用。 |
结果格式
[
'tables' => [
[
'table_name' => '<string>',
'rows' => [
[
'is_ok' => true || false,
'error' => [
'code' => '<string>',
'message' => '<string>',
]
'consumed' => [
'capacity_unit' => [
'read' => <integer>,
'write' => <integer>
]
],
'primary_key' => [
['<string>', <PrimaryKeyValue>],
['<string>', <PrimaryKeyValue>],
['<string>', <PrimaryKeyValue>, <PrimaryKeyType>]
],
'attribute_columns' => [
['<string>', <ColumnValue>, <ColumnType>, <integer>]
['<string>', <ColumnValue>, <ColumnType>, <integer>]
['<string>', <ColumnValue>, <ColumnType>, <integer>]
],
'next_token' => '<string>'
],
//其他行。
]
],
//其他数据表。
]
]
示例
以下示例用于批量一次读取30行,分别从3个数据表中读取数据,每个数据表读取10行。
//从3个数据表中读取数据,每个数据表读取10行。
$tables = array();
for($i = 0; $i < 3; $i++) {
$primary_keys = array();
for($j = 0; $j < 10; $j++) {
$primary_keys[] = [
['pk0', $i],
['pk1', $j]
];
}
$tables[] = [
'table_name' => 'SampleTable' . $i,
'max_versions' => 1,
'primary_keys' => $primary_keys
];
}
$request = [
'tables' => $tables
];
$response = $otsClient->batchGetRow ($request);
//处理返回的每个数据表。
foreach ($response['tables'] as $tableData) {
print "Handling table {$tableData['table_name']} ...\n";
//处理该数据表下的每行数据。
foreach ($tableData['rows'] as $rowData) {
if ($rowData['is_ok']) {
//处理读取到的数据。
$row = json_encode($rowData['primary_key']);
print "Handling row: {$row}\n";
} else {
//处理出错。
print "Error: {$rowData['error']['code']} {$rowData['error']['message']}\n";
}
}
}
详细代码示例请参见下表。
示例 | 说明 |
展示了BatchGetRow获取单个数据表多行的用法。 | |
展示了BatchGetRow获取多个数据表多行的用法。 | |
展示了BatchGetRow获取单个数据表多行同时指定获取特定列的用法。 | |
展示了BatchGetRow处理返回结果的用法。 | |
展示了BatchGetRow同时使用过滤器的用法。 |
范围读取数据
调用GetRange接口读取一个范围内的数据。
GetRange操作支持按照确定范围进行正序读取和逆序读取,可以设置要读取的行数。如果范围较大,已扫描的行数或者数据量超过一定限制,会停止扫描,并返回已获取的行和下一个主键信息。您可以根据返回的下一个主键信息,继续发起请求,获取范围内剩余的行。
表格存储表中的行都是按照主键排序的,而主键是由全部主键列按照顺序组成的,所以不能理解为表格存储会按照某列主键排序,这是常见的误区。
注意事项
GetRange操作遵循最左匹配原则,读取数据时,依次比较第一主键列到第四主键列。例如表的主键包括PK1、PK2、PK3三个主键列,读取数据时,优先比较PK1是否在开始主键与结束主键的范围内,如果PK1在设置的主键范围内,则不会再比较其他的主键,返回在PK1主键范围内的数据;如果PK1在设置的主键边界上,则继续比较PK2是否在开始主键与结束主键的范围内,以此类推。关于范围查询原理的更多信息,请参见GetRange范围查询详解。
GetRange操作可能在如下情况停止执行并返回数据。
扫描的行数据大小之和达到4 MB。
扫描的行数等于5000。
返回的行数等于最大返回行数。
当前剩余的预留读吞吐量已全部使用,余量不足以读取下一条数据。
当使用GetRange扫描的数据量较大时,表格存储每次请求仅会扫描一次(行数大于5000或者大小大于4 MB停止扫描),超过限制的数据不会继续返回,需要通过翻页继续获取后面的数据。
接口
/**
* 范围读起始主键和结束主键间的数据。
* 请注意服务端可能会截断此范围,需要判断返回中的next_start_primary_key来判断是否继续调用GetRange。
* 可以指定最多读取多少行。
* 在指定开始主键和结束主键时,可以使用INF_MIN和INF_MAX分别表示最小值和最大值。更多信息,请参见如下代码样例。
* @api
* @param [] $request 请求参数。
* @return [] 请求返回。
* @throws OTSClientException 当参数检查出错或服务端返回校验出错时。
* @throws OTSServerException 当OTS服务端返回错误时。
*/
public function getRange(array $request);
参数
GetRange和GetRow的区别如下:
primary_key变成inclusive_start_primary_key和exclusive_end_primary_key,范围为前闭后开区间。
增加direction表示读取方向。
增加limit限制返回行数。
参数 | 说明 |
table_name | 数据表名称。 |
inclusive_start_primary_key | 本次范围读的起始主键和结束主键,起始主键和结束主键需要是有效的主键或者是由INF_MIN和INF_MAX类型组成的虚拟点,虚拟点的列数必须与主键相同。 其中INF_MIN表示无限小,任何类型的值都比它大;INF_MAX表示无限大,任何类型的值都比它小。
数据表中的行按主键从小到大排序,读取范围是一个左闭右开的区间,正序读取时,返回的是大于等于起始主键且小于结束主键的所有的行。 |
exclusive_end_primary_key | |
direction | 读取方向。
假设同一表中有两个主键A和B,A小于B。如果正序读取 |
limit | 数据的最大返回行数,此值必须大于0。 表格存储按照正序或者逆序返回指定的最大返回行数后即结束该操作的执行,即使该区间内仍有未返回的数据。此时可以通过返回结果中的next_start_primary_key记录本次读取到的位置,用于下一次读取。 |
max_versions | 最多读取的版本数。 重要 max_versions与time_range必须至少设置一个。
|
time_range | 读取版本号范围或特定版本号的数据。更多信息,请参见TimeRange。 重要 max_versions与time_range必须至少设置一个。
specific_time和 时间戳的单位为毫秒,最小值为0,最大值为 |
columns_to_get | 读取的列集合,列名可以是主键列或属性列。
说明
|
start_column | 读取的起始列,主要用于宽行读,返回的结果中包含当前起始列。 列的顺序按照列名的字典序排序。例如一张表有“a”、“b”、“c”三列,读取时设置start_column为“b”,则会从“b”列开始读,返回“b”、“c”两列。 |
end_column | 读取时的结束列,主要用于宽行读,返回的结果中不包含当前结束列。 列的顺序按照列名的字典序排序。例如一张表有“a”、“b”、“c”三列,读取时指定end_column为“b”,则读到“b”列时会结束,返回“a”列。 |
token | 宽行读取时下一次读取的位置,暂不可用。 |
column_filter | 使用过滤器,在服务端对读取结果再进行一次过滤,只返回符合过滤器中条件的数据行。更多信息,请参见过滤器。 说明 当columns_to_get和column_filter同时使用时,执行顺序是先获取columns_to_get指定的列,再在返回的列中进行条件过滤。 |
请求格式
$result = $client->getRange([
'table_name' => '<string>', //设置表名称。
'inclusive_start_primary_key' => [ //设置起始主键。
['<string>', <PrimaryKeyValue>],
['<string>', <PrimaryKeyValue>],
['<string>', <PrimaryKeyValue>, <PrimaryKeyType>]
],
'exclusive_end_primary_key' => [ //设置结束主键。
['<string>', <PrimaryKeyValue>],
['<string>', <PrimaryKeyValue>],
['<string>', <PrimaryKeyValue>, <PrimaryKeyType>]
],
'direction' => <Direction>, //设置读取方向。
'limit' => <Direction>,
'max_versions' => <integer>,
'time_range' => [
'start_time' => <integer>,
'end_time' => <integer>,
'specific_time' => <integer>
],
'start_column' => '<string>',
'end_column' => '<string>',
'token' => '<string>',
'columns_to_get' => [
'<string>',
'<string>',
//...
],
'column_filter' => <ColumnCondition>
]);
响应参数
参数 | 说明 |
consumed | 本次操作消耗服务能力单元的值。 capacity_unit表示使用的读写能力单元。
|
primary_key | 主键的值,和请求时一致。 |
attribute_columns | 属性列的值。
|
next_start_primary_key | 根据返回结果中的next_start_primary_key判断数据是否全部读取。
|
结果格式
[
'consumed' => [
'capacity_unit' => [
'read' => <integer>,
'write' => <integer>
]
],
'next_start_primary_key' => [
['<string>', <PrimaryKeyValue>],
['<string>', <PrimaryKeyValue>],
['<string>', <PrimaryKeyValue>, <PrimaryKeyType>]
],
'rows' => [
[
'primary_key' => [
['<string>', <PrimaryKeyValue>],
['<string>', <PrimaryKeyValue>],
['<string>', <PrimaryKeyValue>, <PrimaryKeyType>]
],
'attribute_columns' => [
['<string>', <ColumnValue>, <ColumnType>, <integer>]
['<string>', <ColumnValue>, <ColumnType>, <integer>]
['<string>', <ColumnValue>, <ColumnType>, <integer>]
]
],
//其他行。
]
]
示例
以下示例用于按照范围读取数据。
//查找PK0从1到4(左闭右开)的数据。
//范围的边界需要提供完整的主键,如果查询的范围不涉及到某一列值的范围,则需要将该列设置为无穷大(INF_MAX)或者无穷小(INF_MIN)。
$startPK = [
['PK0', 1],
['PK1', null, PrimaryKeyTypeConst::CONST_INF_MIN] //'INF_MIN'表示最小值。
];
//范围的边界需要提供完整的主键,如果查询的范围不涉及到某一列值的范围,则需要将该列设置为无穷大(INF_MAX)或者无穷小(INF_MIN)。
$endPK = [
['PK0', 4],
['PK1', null, PrimaryKeyTypeConst::CONST_INF_MAX] //'INF_MAX'表示最大值。
];
$request = [
'table_name' => 'SampleTable',
'max_versions' => 1, //设置读取最新版本。
'direction' => DirectionConst::CONST_FORWARD, //设置正序查询。
'inclusive_start_primary_key' => $startPK, //设置开始主键。
'exclusive_end_primary_key' => $endPK, //设置结束主键。
'limit' => 10 //设置最多返回10行数据。
];
$response = $otsClient->getRange ($request);
print "Read CU Consumed: {$response['consumed']['capacity_unit']['read']}\n";
foreach ($response['rows'] as $rowData) {
//处理每一行数据。
}
详细代码示例请参见下表。
示例 | 说明 |
展示了GetRange的用法。 | |
展示了GetRange指定获取列的用法。 | |
展示了GetRange指定获取行数限制的用法。 | |
展示了GetRange同时使用过滤器的用法。 |