说明 组成表的基本单位为行,行由主键和属性列组成。其中主键是必须的,且每一行的主键列的名称和类型相同;属性不是必须的,且每一行的属性可以不同。更多信息,请参见宽表模型介绍。
注意事项
当要读取带有自增主键列的表数据时,请确保已获取到包含自增主键列值在内的完整主键。更多信息,请参见主键列自增。
重要 如果未记录自增主键列的值,您可以使用范围读取数据按照第一个主键列确定范围读取数据。
读取单行数据
调用GetRow接口读取一行数据。适用于能确定完整主键且要读取行数较少的场景。
读取单行数据时,您可以配置如下条件过滤所需数据。
系统默认返回所有列,您可以配置只返回指定列的数据。
使用过滤器获取符合过滤条件的行数据。更多信息,请参见过滤器。
如果为数据表配置了数据多版本,则您可以配置最多读取几个版本数据、读取指定时间范围或者指定版本号的数据。关于数据多版本的更多信息,请参见数据版本和生命周期。
读取结果可能有如下两种情况:
批量读取数据
调用BatchGetRow接口一次请求读取多行数据或者一次对多张表进行读取。适用于能确定完整主键,且要读取行数较多或者要读取多个表中数据的场景。
BatchGetRow操作由多个GetRow子操作组成,构造子操作的过程与使用GetRow接口时相同。
批量读取数据时,您可以配置如下条件过滤所需数据。
一次请求中读取多张表中的数据。
单次请求中支持读取的最大行数为100行。
系统默认返回所有列,您可以配置只返回指定列的数据。
批量读取的所有行采用相同的参数条件,例如ColumnsToGet=[colA]
,表示要读取的所有行都只读取colA列。
使用过滤器获取符合过滤条件的行数据。更多信息,请参见过滤器。
如果为数据表配置了数据多版本,则您可以配置最多读取几个版本数据、读取指定时间范围或者指定版本号的数据。关于数据版本的更多信息,请参见数据版本和生命周期。
BatchGetRow操作中的各个子操作独立执行,表格存储会分别返回各个子操作的执行结果。
范围读取数据
调用GetRange接口读取一个范围内的数据。适用于能确定完整主键范围或者主键前缀的场景。
说明 表格存储表中的行都是按照主键排序的,而主键是由全部主键列按照顺序组成的,所以不能理解为表格存储会按照某列主键排序,这是常见的误区。
GetRange操作遵循最左匹配原则,读取数据时,依次比较第一主键列到第四主键列。例如表的主键包括PK1、PK2、PK3三个主键列,读取数据时,优先比较PK1是否在开始主键与结束主键的范围内,如果PK1在设置的主键范围内,则不会再比较其他的主键,返回在PK1主键范围内的数据;如果PK1在设置的主键边界上,则继续比较PK2是否在开始主键与结束主键的范围内,以此类推。
范围读取数据时,您可以配置如下条件过滤所需数据。
指定主键前缀后其他主键列使用虚拟点INF_MIN(无穷小)和INF_MAX(无穷大)读取数据,或者指定完整主键范围读取数据。
重要 如果不能确定主键前缀,您也可以通过设置完整主键范围均为虚拟点INF_MIN和INF_MAX进行全表数据扫描,但是执行此操作会消耗较多计算资源,请谨慎使用。
如果范围较大,已扫描的行数或者数据量超过一定限制,会停止扫描,并返回已获取的行和下一个主键信息。您可以根据返回的下一个主键信息,继续发起请求,获取范围内剩余的行。
GetRange操作可能在如下情况停止执行并返回数据。
按照正序或者逆序读取最多指定个数的行数据,例如按照正序读取最多5行数据。
系统默认返回所有列,您可以配置只返回指定列的数据。
使用过滤器获取符合过滤条件的行数据。更多信息,请参见过滤器。
范围读取的所有行采用相同的参数条件,例如ColumnsToGet=[colA]
,表示要读取的所有行都只读取colA列。
如果为数据表配置了数据多版本,则您可以配置最多读取几个版本数据、读取指定时间范围或者指定版本号的数据。关于数据版本的更多信息,请参见数据版本和生命周期。
当使用GetRange扫描的数据量较大时,表格存储每次请求仅会扫描一次(行数大于5000或者大小大于4 MB停止扫描),超过限制的数据不会继续返回,需要通过翻页继续获取后面的数据。
使用方式
使用控制台
您可以使用控制台进行单行查询数据或范围查询数据。
登录表格存储控制台。
在概览页面,单击实例操作列的实例管理。
在实例详情页签的数据表列表区域,单击数据表操作列的查询/搜索。
在数据管理页签,单击查询数据,根据实际选择单行读取数据或者范围读取数据。
读取单行数据
在查询数据对话框,选择查询范围为单行查询,并选择要查询的表。
系统默认返回所有列。如需显示指定属性列,请关闭获取所有列并输入需要返回的属性列。
多个属性列之间用半角逗号(,)隔开。
输入目标行的主键值。
主键值的完整性和准确性均会影响查询。
输入最大版本数,指定需要返回的版本数。
单击确定。
范围读取数据
在查询数据对话框,选择查询范围为范围查询,并选择要查询的表。
系统默认返回所有列。如需显示指定属性列,请关闭获取所有列并输入需要返回的属性列。
多个属性列之间用半角逗号(,)隔开。
输入起始主键列和结束主键列。
输入最大版本数,指定需要返回的版本数。
设置查询结果的排序方向,可选正序查询或逆序查询。
单击确定。
使用命令行工具CLI
您可以使用命令行工具执行如下命令读取数据。
执行get
命令读取单行数据。更多信息,请参见读取数据。
以下示例用于读取第一主键列值为“86”,第二主键列值为6771的行数据。
get --pk '["86",6771]'
执行scan
命令范围读取数据。更多信息,请参见导出数据。
以下示例用于逆序读取["86",7000]
到["86",6770]
主键范围之间的行数据,且只返回pid列。
scan --begin '["86",7000]' --end '["86",6770]' --backward --columns pid
使用SDK
您可以使用Java SDK、Go SDK、Python SDK、Node.js SDK、.NET SDK和PHP SDK读取数据。此处以Java SDK为例介绍读取数据的使用。
读取单行数据
读取数据时,您可以指定要读取的数据版本、要读取的列、过滤器、正则过滤等。
读取最新版本数据和指定列
以下示例用于读取数据表中的一行数据,设置读取最新版本的数据和读取指定的列。
private static void getRow(SyncClient client, String pkValue) {
//构造主键。
PrimaryKeyBuilder primaryKeyBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
primaryKeyBuilder.addPrimaryKeyColumn("pk", PrimaryKeyValue.fromString(pkValue));
PrimaryKey primaryKey = primaryKeyBuilder.build();
//读取一行数据,设置数据表名称。
SingleRowQueryCriteria criteria = new SingleRowQueryCriteria("<TABLE_NAME>", primaryKey);
//设置读取最新版本。
criteria.setMaxVersions(1);
GetRowResponse getRowResponse = client.getRow(new GetRowRequest(criteria));
Row row = getRowResponse.getRow();
System.out.println("读取完毕,结果为: ");
System.out.println(row);
//设置读取某些列。
criteria.addColumnsToGet("Col0");
getRowResponse = client.getRow(new GetRowRequest(criteria));
row = getRowResponse.getRow();
System.out.println("读取完毕,结果为:");
System.out.println(row);
}
读取数据时使用过滤器
以下示例用于读取数据表中的一行数据,设置读取最新版本的数据以及根据Col0列的值过滤数据。
private static void getRow(SyncClient client, String pkValue) {
//构造主键。
PrimaryKeyBuilder primaryKeyBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
primaryKeyBuilder.addPrimaryKeyColumn("pk", PrimaryKeyValue.fromString(pkValue));
PrimaryKey primaryKey = primaryKeyBuilder.build();
//读取一行数据,设置数据表名称。
SingleRowQueryCriteria criteria = new SingleRowQueryCriteria("<TABLE_NAME>", primaryKey);
//设置读取最新版本。
criteria.setMaxVersions(1);
//设置过滤器,当Col0列的值为0时,返回该行。
SingleColumnValueFilter singleColumnValueFilter = new SingleColumnValueFilter("Col0",
SingleColumnValueFilter.CompareOperator.EQUAL, ColumnValue.fromLong(0));
//如果Col0列不存在,则不返回该行。
singleColumnValueFilter.setPassIfMissing(false);
criteria.setFilter(singleColumnValueFilter);
GetRowResponse getRowResponse = client.getRow(new GetRowRequest(criteria));
Row row = getRowResponse.getRow();
System.out.println("读取完毕,结果为: ");
System.out.println(row);
}
读取数据时使用正则过滤
以下示例用于读取数据表一行中Col1列的数据,并对该列的数据执行正则过滤。
private static void getRow(SyncClient client, String pkValue) {
//设置数据表名称。
SingleRowQueryCriteria criteria = new SingleRowQueryCriteria("<TABLE_NAME>");
//构造主键。
PrimaryKey primaryKey = PrimaryKeyBuilder.createPrimaryKeyBuilder()
.addPrimaryKeyColumn("pk", PrimaryKeyValue.fromString(pkValue))
.build();
criteria.setPrimaryKey(primaryKey);
// 设置读取最新版本。
criteria.setMaxVersions(1);
// 设置过滤器,当cast<int>(regex(Col1)) > 100时,返回该行。
RegexRule regexRule = new RegexRule("t1:([0-9]+),", RegexRule.CastType.VT_INTEGER);
SingleColumnValueRegexFilter filter = new SingleColumnValueRegexFilter("Col1",
regexRule,SingleColumnValueRegexFilter.CompareOperator.GREATER_THAN, ColumnValue.fromLong(100));
criteria.setFilter(filter);
GetRowResponse getRowResponse = client.getRow(new GetRowRequest(criteria));
Row row = getRowResponse.getRow();
System.out.println("读取完毕,结果为: ");
System.out.println(row);
}
批量读取数据
以下示例用于读取10行,设置版本条件、要读取的列、过滤器等。
private static void batchGetRow(SyncClient client) {
//设置数据表名称。
MultiRowQueryCriteria multiRowQueryCriteria = new MultiRowQueryCriteria("<TABLE_NAME>");
//加入10个要读取的行。
for (int i = 0; i < 10; i++) {
PrimaryKeyBuilder primaryKeyBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
primaryKeyBuilder.addPrimaryKeyColumn("pk", PrimaryKeyValue.fromString("pk" + i));
PrimaryKey primaryKey = primaryKeyBuilder.build();
multiRowQueryCriteria.addRow(primaryKey);
}
//添加条件。
multiRowQueryCriteria.setMaxVersions(1);
multiRowQueryCriteria.addColumnsToGet("Col0");
multiRowQueryCriteria.addColumnsToGet("Col1");
SingleColumnValueFilter singleColumnValueFilter = new SingleColumnValueFilter("Col0",
SingleColumnValueFilter.CompareOperator.EQUAL, ColumnValue.fromLong(0));
singleColumnValueFilter.setPassIfMissing(false);
multiRowQueryCriteria.setFilter(singleColumnValueFilter);
BatchGetRowRequest batchGetRowRequest = new BatchGetRowRequest();
//BatchGetRow支持读取多个表的数据,一个multiRowQueryCriteria对应一个表的查询条件,可以添加多个multiRowQueryCriteria。
batchGetRowRequest.addMultiRowQueryCriteria(multiRowQueryCriteria);
BatchGetRowResponse batchGetRowResponse = client.batchGetRow(batchGetRowRequest);
System.out.println("是否全部成功:" + batchGetRowResponse.isAllSucceed());
System.out.println("读取完毕,结果为: ");
for (BatchGetRowResponse.RowResult rowResult : batchGetRowResponse.getSucceedRows()) {
System.out.println(rowResult.getRow());
}
if (!batchGetRowResponse.isAllSucceed()) {
for (BatchGetRowResponse.RowResult rowResult : batchGetRowResponse.getFailedRows()) {
System.out.println("失败的行:" + batchGetRowRequest.getPrimaryKey(rowResult.getTableName(), rowResult.getIndex()));
System.out.println("失败原因:" + rowResult.getError());
}
/**
* 可以通过createRequestForRetry方法再构造一个请求对失败的行进行重试。此处只给出构造重试请求的部分。
* 推荐的重试方法是使用SDK的自定义重试策略功能,支持对batch操作的部分行错误进行重试。设置重试策略后,调用接口处无需增加重试代码。
*/
BatchGetRowRequest retryRequest = batchGetRowRequest.createRequestForRetry(batchGetRowResponse.getFailedRows());
}
}
范围读取数据
按照确定范围读取数据
以下示例用于按照确定范围进行正序读取,判断nextStartPrimaryKey是否为空,读取完范围内的全部数据。
private static void getRange(SyncClient client, String startPkValue, String endPkValue) {
//设置数据表名称。
RangeRowQueryCriteria rangeRowQueryCriteria = new RangeRowQueryCriteria("<TABLE_NAME>");
//设置起始主键。
PrimaryKeyBuilder primaryKeyBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
primaryKeyBuilder.addPrimaryKeyColumn("pk", PrimaryKeyValue.fromString(startPkValue));
rangeRowQueryCriteria.setInclusiveStartPrimaryKey(primaryKeyBuilder.build());
//设置结束主键。
primaryKeyBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
primaryKeyBuilder.addPrimaryKeyColumn("pk", PrimaryKeyValue.fromString(endPkValue));
rangeRowQueryCriteria.setExclusiveEndPrimaryKey(primaryKeyBuilder.build());
rangeRowQueryCriteria.setMaxVersions(1);
System.out.println("GetRange的结果为:");
while (true) {
GetRangeResponse getRangeResponse = client.getRange(new GetRangeRequest(rangeRowQueryCriteria));
for (Row row : getRangeResponse.getRows()) {
System.out.println(row);
}
//如果NextStartPrimaryKey不为null,则继续读取。
if (getRangeResponse.getNextStartPrimaryKey() != null) {
rangeRowQueryCriteria.setInclusiveStartPrimaryKey(getRangeResponse.getNextStartPrimaryKey());
} else {
break;
}
}
}
按照第一个主键列确定范围读取数据
以下示例用于按照第一个主键列确定范围、第二主键列从最小值(INF_MIN)到最大值(INF_MAX)进行正序读取,判断nextStartPrimaryKey是否为null,读取完范围内的全部数据。
private static void getRange(SyncClient client, String startPkValue, String endPkValue) {
//设置数据表名称。
RangeRowQueryCriteria rangeRowQueryCriteria = new RangeRowQueryCriteria("<TABLE_NAME>");
//设置起始主键,以两个主键为例。
PrimaryKeyBuilder primaryKeyBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
primaryKeyBuilder.addPrimaryKeyColumn("pk1", PrimaryKeyValue.fromString(startPkValue));//确定值。
primaryKeyBuilder.addPrimaryKeyColumn("pk2", PrimaryKeyValue.INF_MIN);//最小值。
rangeRowQueryCriteria.setInclusiveStartPrimaryKey(primaryKeyBuilder.build());
//设置结束主键。
primaryKeyBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
primaryKeyBuilder.addPrimaryKeyColumn("pk1", PrimaryKeyValue.fromString(endPkValue));//确定值。
primaryKeyBuilder.addPrimaryKeyColumn("pk2", PrimaryKeyValue.INF_MAX);//最大值。
rangeRowQueryCriteria.setExclusiveEndPrimaryKey(primaryKeyBuilder.build());
rangeRowQueryCriteria.setMaxVersions(1);
System.out.println("GetRange的结果为:");
while (true) {
GetRangeResponse getRangeResponse = client.getRange(new GetRangeRequest(rangeRowQueryCriteria));
for (Row row : getRangeResponse.getRows()) {
System.out.println(row);
}
//如果nextStartPrimaryKey不为null,则继续读取。
if (getRangeResponse.getNextStartPrimaryKey() != null) {
rangeRowQueryCriteria.setInclusiveStartPrimaryKey(getRangeResponse.getNextStartPrimaryKey());
} else {
break;
}
}
}
按照确定范围读取数据并对指定列使用正则过滤
以下示例用于读取主键范围为["pk:2020-01-01.log", "pk:2021-01-01.log")
时Col1列的数据,并对该列的数据执行正则过滤。
private static void getRange(SyncClient client) {
//设置数据表名称。
RangeRowQueryCriteria criteria = new RangeRowQueryCriteria("<TABLE_NAME>");
//设置主键范围为["pk:2020-01-01.log", "pk:2021-01-01.log"),读取范围为左闭右开的区间。
PrimaryKey pk0 = PrimaryKeyBuilder.createPrimaryKeyBuilder()
.addPrimaryKeyColumn("pk", PrimaryKeyValue.fromString("2020-01-01.log"))
.build();
PrimaryKey pk1 = PrimaryKeyBuilder.createPrimaryKeyBuilder()
.addPrimaryKeyColumn("pk", PrimaryKeyValue.fromString("2021-01-01.log"))
.build();
criteria.setInclusiveStartPrimaryKey(pk0);
criteria.setExclusiveEndPrimaryKey(pk1);
//设置读取最新版本。
criteria.setMaxVersions(1);
//设置过滤器,当cast<int>(regex(Col1)) > 100时,返回该行。
RegexRule regexRule = new RegexRule("t1:([0-9]+),", RegexRule.CastType.VT_INTEGER);
SingleColumnValueRegexFilter filter = new SingleColumnValueRegexFilter("Col1",
regexRule,SingleColumnValueRegexFilter.CompareOperator.GREATER_THAN,ColumnValue.fromLong(100));
criteria.setFilter(filter);
while (true) {
GetRangeResponse resp = client.getRange(new GetRangeRequest(criteria));
for (Row row : resp.getRows()) {
// do something
System.out.println(row);
}
if (resp.getNextStartPrimaryKey() != null) {
criteria.setInclusiveStartPrimaryKey(resp.getNextStartPrimaryKey());
} else {
break;
}
}
}
计费说明
根据实际计算消耗折算成CU进行计费。同时根据实例类型不同,计费时需要区分按量读写CU以及预留读写CU。
读取数据时不消耗写CU,消耗的读CU计算规则如下:
GetRow操作消耗的读CU
读取的行主键的数据大小与实际读取的属性列数据大小之和,按4 KB向上取整。如果操作指定的行不存在,则消耗1单位读CU。
BatchGetRow操作消耗的读CU
按照将每个RowInBatchGetRowRequest视为一个GetRow操作独立计算读CU。
GetRange操作消耗的读CU
从区间起始点到下一条未读数据的起始点,所有行主键数据大小与实际扫描的所有属性列数据大小之和按4 KB向上取整计算消耗的读CU。例如扫描范围中包含10行数据,每行主键数据大小与实际扫描的所有属性列数据之和为330 Byte,则消耗的读CU为1(数据总和3.3 KB,除以4 KB向上取整为1)。