表格存储的基础数据操作包括单行数据操作和多行数据操作,用于读写表中数据。

接口

组成表的基本单位为行,行由主键和属性组成。其中主键是必须的,且每一行的主键列的名称和类型相同;属性不是必须的,且每一行的属性可以不同。详情请参见模型介绍

表格存储的数据操作类型有两种,不同操作类型的接口说明请参见下表。
操作类型 接口 说明
单行数据操作 GetRow 读取一行数据。
PutRow 新写入一行数据。如果该行已存在,则先删除旧行数据,再写入新行数据。
UpdateRow 更新一行数据。可以增加、删除一行中的属性列,或者更新已存在的属性列的值。

如果更新的行不存在,则新增一行数据。但是当UpdateRow请求中只包含删除指定的列且该行不存在时,则该请求不会新增一行数据。

DeleteRow 删除一行数据。

如果删除的行不存在,则不会发生任何变化。

多行数据操作 BatchGetRow 批量读取一个或多个表中多行数据。
BatchWriteRow 批量插入、更新或者删除一个或多个表中的多行数据。
GetRange 读取表中指定主键范围内的数据。

单行数据操作

  • 单行写入操作
    单行写入操作包括PutRow、UpdateRow和DeleteRow,不同的操作结果返回的结果不同。
    • 如果操作成功,表格存储会返回操作消耗的服务能力单元(CU)。
      单行写入操作消耗的CU计算规则请参见下表。
      说明 写入操作会根据指定的condition情况消耗一定的读CU。
      接口 CU计算规则
      PutRow PutRow操作消耗的读CU和写CU的说明如下:
      • 消耗的写CU为修改的行主键数据大小与属性列数据大小之和除以4 KB向上取整。
      • 如果指定条件检查不为IGNORE,则消耗行主键数据大小除以4 KB向上取整的读CU。
      • 如果操作不满足指定的行存在性检查条件,则操作失败并消耗1单位写CU和1单位读CU。
      UpdateRow UpdateRow操作消耗的读CU和写CU的说明如下:
      • 消耗的写CU为修改的行主键数据大小与属性列数据大小之和除以4 KB向上取整。

        操作中包含的需要删除的属性列,只有属性列的列名计入属性列数据大小。

      • 如果指定条件检查不为IGNORE,则消耗行主键数据大小除以4 KB向上取整的读CU。
      • 如果操作不满足指定的行存在性检查条件,则操作失败并消耗1单位写CU和1单位读CU。
      DeleteRow DeleteRow操作消耗的读CU和写CU的说明如下:
      • 消耗的写CU为删除的行主键数据大小除以4 KB向上取整。
      • 如果指定条件检查不为IGNORE,则消耗行主键数据大小除以4 KB向上取整的读CU。
      • 如果操作不满足指定的行存在性检查条件,则操作失败并消耗1单位写CU。
    • 如果操作发生错误,例如参数检查失败、单行数据量过多、行存在性检查失败等,表格存储会返回错误码。
    通过在单行写入请求中设置condition字段可以指定写入操作执行时,是否对行的存在性进行检查。condition有如下三种类型:
    condition 说明
    IGNORE 不做任何存在性检查。
    EXPECT_EXIST 期望行存在。
    • 如果该行存在,则操作成功。
    • 如果该行不存在,则操作失败。
    EXPECT_NOT_EXIST 期望行不存在。
    • 如果该行不存在,则操作成功。
    • 如果该行存在,则操作失败。
    说明 condition为EXPECT_NOT_EXIST的DeleteRow、UpdateRow操作是无意义的,即删除一个不存在的行是无意义的。如果需要更新不存在的行可以使用PutRow操作。

    参数

    单行写入操作的参数说明请参见下表。
    参数 说明
    primary_keys 主键列的列名和值。
    attributes 属性列的列名和值。

    示例

    如下举例说明单行写入操作消耗的写CU和读CU的计算。

    • 示例1

      使用PutRow进行单行写入操作。

      写CU和读CU的消耗情况如下:
      • 当condition设置为EXPECT_EXIST时,消耗的写CU为4322 Byte除以4 KB向上取整,消耗的读CU为行主键数据大小10 Byte除以4 KB向上取整。该PutRow操作消耗2单位写CU和1单位读CU。
      • 当condition设置为IGNORE时,消耗的写CU为4322 Byte除以4 KB向上取整,消耗0单位读CU。该PutRow操作消耗2单位写CU和0单位读CU。
      • 当condition设置为EXPECT_NOT_EXIST时,指定的行存在性检查条件检查失败,该PutRow操作消耗1单位写CU和1单位读CU。
      //PutRow操作
      //row_size=len('pk')+len('value1')+len('value2')+8Byte+1300Byte+3000Byte=4322Byte
      {
          primary_keys:{'pk':1},
          attributes:{'value1':String(1300Byte), 'value2':String(3000Byte)}
      }
      
      //原来的行
      //row_size=len('pk')+len('value2')+8Byte+900Byte=916Byte
      //row_primarykey_size=len('pk')+8Byte=10Byte
      {
          primary_keys:{'pk':1},
          attributes:{'value2':String(900Byte)}
      }
                                  
    • 示例2

      使用UpdateRow新写入一行数据。

      写CU和读CU的消耗情况如下:
      • 当condition设置为IGNORE时,消耗的写CU为922 Byte除以4 KB向上取整,消耗0个读CU。该UpdateRow操作消耗1单位写CU和0单位读CU。
      • 当condition设置为EXPECT_EXIST时,指定的行存在性检查条件检查失败,该PutRow操作消耗1单位写CU和1单位读CU。
      //UpdateRow操作
      //删除的属性列列名长度计入row_size
      //row_size=len('pk')+len('value1')+len('value2')+8Byte+900Byte=922Byte
      {
          primary_keys:{'pk':1},
          attributes:{'value1':String(900Byte), 'value2':Delete}
      }
      
      //原来的行不存在
      //row_size=0
                                  
    • 示例3

      使用UpdateRow对存在的行进行更新操作。

      写CU和读CU的消耗情况如下:
      • 当condition设置为EXPECT_EXIST时,消耗的写CU为4322 Byte除以4 KB向上取整,消耗的读CU为行主键数据大小10 Byte除以4 KB向上取整。该UpdateRow操作消耗2单位写CU和1单位读CU。
      • 当condition设置为IGNORE时,消耗的写CU为4322 Byte除以4 KB向上取整,消耗0个单位读CU,该UpdateRow操作消耗2单位写CU和0单位读CU。
      //UpdateRow操作
      //row_size=len('pk')+len('value1')+len('value2')+8 Byte+1300 Byte+3000 Byte=4322 Byte
      {
          primary_keys:{'pk':1},
          attributes:{'value1':String(1300 Byte), 'value2':String(3000 Byte)}
      }
      //原来的行
      //row_size=len('pk')+len('value1')+8 Byte+900 Byte=916 Byte
      //row_primarykey_size=len('pk')+8 Byte=10 Byte
      {
          primary_keys:{'pk':1},
          attributes:{'value1':String(900 Byte)}
      }
                                  
    • 示例4

      使用DeleteRow删除不存在的行。

      由于修改前后的数据大小均为0,无论读写操作成功还是失败至少消耗1单位CU。因此该DeleteRow操作消耗1单位写CU。

      写CU和读CU的消耗情况如下:
      • 当condition设置为EXPECT_EXIST时,消耗的写CU为行主键数据大小10 Byte除以4 KB向上取整,消耗的读CU为行主键数据大小10 Byte除以4 KB向上取整。该DeleteRow操作消耗1单位写CU和1单位读CU。
      • 当condition设置为IGNORE时,消耗的写CU为行主键数据大小10 Byte除以4 KB向上取整,消耗0单位读CU。该DeleteRow操作消耗1单位写CU和0个单位读CU。
      //原来的行不存在
      //row_size=0
      
      //DeleteRow操作
      //row_size=0
      //row_primarykey_size=len('pk')+8 Byte=10 Byte
      {
          primary_keys:{'pk':1},
      }
                                  
  • 单行读取操作

    单行读取操作只包括GetRow,使用GetRow时需要提供完整的主键和设置返回的列名。

    单行读取操作不消耗写CU,消耗的读CU为读取的行主键的数据大小与实际读取的属性列数据大小之和,按4 KB向上取整。如果操作指定的行不存在,则消耗1单位读CU。详情请参见GetRow

    参数

    单行读取操作的参数说明请参见下表。
    参数 说明
    primary_keys 主键列的列名和值。
    attributes 属性列的列名和值。
    columns_to_get 返回的列名,列名可以是主键列或属性列。

    如果不指定返回的列名,则返回整行数据。

    示例

    使用GetRow读取一行数据。

    消耗的读CU为1216 Byte除以4 KB向上取整,该GetRow操作消耗1单位读CU。

    //读取的行
    
    //row_size=len('pk')+len('value1')+len('value2')+8 Byte+1200 Byte+3100 Byte=4322 Byte
    {
        primary_keys:{'pk':1},
        attributes:{'value1':String(1200 Byte), 'value2':String(3100 Byte)}
    }
    
    //GetRow操作
    //获取的数据size=len('pk')+len('value1')+8 Byte+1200 Byte=1216 Byte
    {
        primary_keys:{'pk':1},
        columns_to_get:{'value1'}
    }
                        

多行数据操作

  • 批量写入操作
    批量写入操作只包括BatchWriteRow,BatchWriteRow操作由多个PutRow、UpdateRow、DeleteRow子操作组成。
    • BatchWriteRow的各个子操作独立执行,表格存储会分别返回各个子操作的执行结果。

      由于返回结果可能存在部分请求成功、部分请求失败的情况。即使整个请求没有返回错误,应用程序也会检查每个子操作的返回结果,从而拿到正确的状态。

    • BatchWriteRow的各个子操作单独计算写CU和读CU。详情请参见BatchWriteRow
  • 批量读取操作

    批量读取操作只包括BatchGetRow,BatchGetRow由多个GetRow子操作组成。

    • BatchGetRow的各个子操作独立执行,表格存储会分别返回各个子操作的执行结果。

      由于返回结果可能存在部分请求成功、部分请求失败的情况。即使整个请求没有返回错误,应用程序也会检查每个子操作的返回结果,从而拿到正确的状态。

    • BatchGetRow的各个子操作单独计算读服务能力单元。详情请参见BatchGetRow
  • 范围读取操作
    范围读取操作只包括GetRange,用于返回指定主键范围内的行数据。
    • GetRange操作消耗的读CU为从区间起始点到下一条未读数据的起始点,所有行主键数据大小与实际扫描的所有属性列数据大小之和按4 KB向上取整计算消耗的读CU。详情请参见GetRange

      例如扫描范围中包含10行,每行主键数据大小与实际扫描的所有属性列数据之和为330 Byte,则消耗的读CU为1(数据总和3.3 KB,除以4 KB向上取整为1)。

    • GetRange操作可能在如下情况停止执行并返回数据。
      • 扫描的行数据大小之和达到4 MB。
      • 扫描的行数等于5000。
      • 返回的行数等于最大返回行数。
      • 当前剩余的预留读吞吐量已全部使用,余量不足以读取下一条数据。

    参数

    范围读取操作的参数说明请参见下表。
    参数 说明
    table_name 数据表的名称。
    direction 读取方向,读取方向可以为正序或逆序。

    例如同一表中有两个主键A和B,A<B。如正序读取[A, B),则按从A至B的顺序返回主键大于等于A、小于B的行;逆序读取[B, A),则按从B至A的顺序返回大于A、小于等于B的数据。

    inclusive_start_primary_key 读取的主键范围,数据表中的行按主键从小到大排序,读取范围是一个左闭右开的区间,区间的起始点是有效的主键或者是由INF_MIN和INF_MAX类型组成的虚拟点,虚拟点的列数必须与主键相同。

    其中INF_MIN表示无限小,任何类型的值都比它大;INF_MAX表示无限大,任何类型的值都比它小。

    exclusive_end_primary_key
    columns_to_get 返回的请求列名,请求列名中可以包含多个列名,如果不指定请求列名,则返回完整的行。

    如果某行数据的主键属于读取范围,但是该行数据不包含指定返回的列,那么返回结果中不包含该行数据。

    limit 数据的最大返回行数。

    表格存储按照正序或者逆序返回指定的最大返回行数后即结束该操作的执行,即使该区间内仍有未返回的数据。

    cosumed_read_capacity_unit 消耗的读CU。
    primary_keys 主键列的列名和值。
    attributes 属性列的列名和值。
    next_start_primary_key 根据返回结果中的next_start_primary_key判断数据是否全部读取。
    • 当返回结果中next_start_primary_key不为空时,可以使用此返回值作为下一次GetRange操作的起始点继续读取数据。
    • 当返回结果中next_start_primary_key为空,表示读取区间内的数据全部返回。

    示例

    如下举例说明GetRange操作的行为。

    例如数据表的内容如下,PK1、PK2是数据表的主键列,类型分别为String和Integer;Attr1、Attr2是数据表的属性列。
    PK1 PK2 Attr1 Attr2
    'A' 2 'Hell' 'Bell'
    'A' 5 'Hello' 不存在
    'A' 6 不存在 'Blood'
    'B' 10 'Apple' 不存在
    'C' 1 不存在 不存在
    'C' 9 'Alpha' 不存在
    • 示例1

      读取某一范围内的数据。

      //请求
      table_name: "table_name"
      direction: FORWARD
      inclusive_start_primary_key: ("PK1", STRING, "A"), ("PK2", INTEGER, 2)
      exclusive_end_primary_key: ("PK1", STRING, "C"), ("PK2", INTEGER, 1)
      
      //响应
      cosumed_read_capacity_unit: 1
      rows: {
            {
              primary_key_columns:("PK1", STRING, "A"), ("PK2", INTEGER, 2)
              attribute_columns:("Attr1", STRING, "Hell"), ("Attr2", STRING, "Bell")
            },
            {
              primary_key_columns:("PK1", STRING, "A"), ("PK2", INTEGER, 5)
              attribute_columns:("Attr1", STRING, "Hello")
            },
            {
              primary_key_columns:("PK1", STRING, "A"), ("PK2", INTEGER, 6)
              attribute_columns:("Attr2", STRING, "Blood")
            },
            {
              primary_key_columns:("PK1", STRING, "B"), ("PK2", INTEGER, 10)
              attribute_columns:("Attr1", STRING, "Apple")
            }
          }
                                  
    • 示例2

      使用INF_MIN和INF_MAX读取数据表全部数据。

      //请求
      table_name: "table_name"
      direction: FORWARD
      inclusive_start_primary_key: ("PK1", INF_MIN)
      exclusive_end_primary_key: ("PK1", INF_MAX)
      
      //响应
      cosumed_read_capacity_unit: 1
      rows: {
            {
              primary_key_columns:("PK1", STRING, "A"), ("PK2", INTEGER, 2)
              attribute_columns:("Attr1", STRING, "Hell"), ("Attr2", STRING, "Bell")
            },
            {
              primary_key_columns:("PK1", STRING, "A"), ("PK2", INTEGER, 5)
              attribute_columns:("Attr1", STRING, "Hello")
            },
            {
              primary_key_columns:("PK1", STRING, "A"), ("PK2", INTEGER, 6)
              attribute_columns:("Attr2", STRING, "Blood")
            },
            {
              primary_key_columns:("PK1", STRING, "B"), ("PK2", INTEGER, 10)
              attribute_columns:("Attr1", STRING, "Apple")
            }
            {
              primary_key_columns:("PK1", STRING, "C"), ("PK2", INTEGER, 1)
            }
            {
              primary_key_columns:("PK1", STRING, "C"), ("PK2", INTEGER, 9)
              attribute_columns:("Attr1", STRING, "Alpha")
            }
          }
                                  
    • 示例3

      在某些主键列上使用INF_MIN和INF_MAX。

      //请求
      table_name: "table_name"
      direction: FORWARD
      inclusive_start_primary_key: ("PK1", STRING, "A"), ("PK2", INF_MIN)
      exclusive_end_primary_key: ("PK1", STRING, "A"), ("PK2", INF_MAX)
      
      //响应
      cosumed_read_capacity_unit: 1
      rows: {
            {
              primary_key_columns:("PK1", STRING, "A"), ("PK2", INTEGER, 2)
              attribute_columns:("Attr1", STRING, "Hell"), ("Attr2", STRING, "Bell")
            },
            {
              primary_key_columns:("PK1", STRING, "A"), ("PK2", INTEGER, 5)
              attribute_columns:("Attr1", STRING, "Hello")
            },
            {
              primary_key_columns:("PK1", STRING, "A"), ("PK2", INTEGER, 6)
              attribute_columns:("Attr2", STRING, "Blood")
            }
          }
                                  
    • 示例4

      逆序读取数据。

      //请求
      table_name: "table_name"
      direction: BACKWARD
      inclusive_start_primary_key: ("PK1", STRING, "C"), ("PK2", INTEGER, 1)
      exclusive_end_primary_key: ("PK1", STRING, "A"), ("PK2", INTEGER, 5)
      
      //响应
      cosumed_read_capacity_unit: 1
      rows: {
            {
              primary_key_columns:("PK1", STRING, "C"), ("PK2", INTEGER, 1)
            },
            {
              primary_key_columns:("PK1", STRING, "B"), ("PK2", INTEGER, 10)
              attribute_columns:("Attr1", STRING, "Apple")
            },
            {
              primary_key_columns:("PK1", STRING, "A"), ("PK2", INTEGER, 6)
              attribute_columns:("Attr2", STRING, "Blood")
            }
          }
                                  
    • 示例5

      指定列名不包含主键列。

      //请求
      table_name: "table_name"
      direction: FORWARD
      inclusive_start_primary_key: ("PK1", STRING, "C"), ("PK2", INF_MIN)
      exclusive_end_primary_key: ("PK1", STRING, "C"), ("PK2", INF_MAX)
      columns_to_get: "Attr1"
      
      //响应
      cosumed_read_capacity_unit: 1
      rows: {
            {
              attribute_columns: {"Attr1", STRING, "Alpha"}
            }
          }
                                  
    • 示例6

      指定列名中包含主键列。

      //请求
      table_name: "table_name"
      direction: FORWARD
      inclusive_start_primary_key: ("PK1", STRING, "C"), ("PK2", INF_MIN)
      exclusive_end_primary_key: ("PK1", STRING, "C"), ("PK2", INF_MAX)
      columns_to_get: "Attr1", "PK1"
      
      //响应
      cosumed_read_capacity_unit: 1
      rows: {
            {
              primary_key_columns:("PK1", STRING, "C")
            }
            {
              primary_key_columns:("PK1", STRING, "C")
              attribute_columns:("Attr1", STRING, "Alpha")
            }
          }
                                  
    • 示例7

      使用limit和断点。

      //请求1
      table_name: "table_name"
      direction: FORWARD
      inclusive_start_primary_key: ("PK1", STRING, "A"), ("PK2", INF_MIN)
      exclusive_end_primary_key: ("PK1", STRING, "A"), ("PK2", INF_MAX)
      limit: 2
      
      //响应1
      cosumed_read_capacity_unit: 1
      rows: {
            {
              primary_key_columns:("PK1", STRING, "A"), ("PK2", INTEGER, 2)
              attribute_columns:("Attr1", STRING, "Hell"), ("Attr2", STRING, "Bell")
            },
            {
              primary_key_columns:("PK1", STRING, "A"), ("PK2", INTEGER, 5)
              attribute_columns:("Attr1", STRING, "Hello")
            }
          }
      next_start_primary_key:("PK1", STRING, "A"), ("PK2", INTEGER, 6)
      
      //请求2
      table_name: "table_name"
      direction: FORWARD
      inclusive_start_primary_key: ("PK1", STRING, "A"), ("PK2", INTEGER, 6)
      exclusive_end_primary_key: ("PK1", STRING, "A"), ("PK2", INF_MAX)
      limit: 2
      
      //响应2
      cosumed_read_capacity_unit: 1
      rows: {
            {
              primary_key_columns:("PK1", STRING, "A"), ("PK2", INTEGER, 6)
              attribute_columns:("Attr2", STRING, "Blood")
            }
          }
                                  
    • 示例8
      使用GetRange操作消耗的读CU计算。此次GetRange请求中消耗的读CU为扫描的三行数据之和11 Byte+24 Byte+1016 Byte=1051 Byte除以4 KB向上取整,该GetRange操作消耗1单位读CU。具体说明如下:
      • 第一行数据大小为:len ('PK1')+8 Byte=11 Byte
      • 第二行数据大小为:len ('PK1')+8 Byte+len ('Attr1')+8 Byte=24 Byte
      • 第三行数据大小为:len ('PK1')+8 Byte+len ('Attr1')+1000 Byte=1016 Byte

      在如下数据表中执行GetRange操作,其中PK1是数据表的主键列,Attr1、Attr2是数据表的属性列。

      PK1 Attr1 Attr2
      1 不存在 String(1000 Byte)
      2 8 String(1000 Byte)
      3 String(1000 Byte) 不存在
      4 String(1000 Byte) String(1000 Byte)
      //请求
      table_name: "table2_name"
      direction: FORWARD
      inclusive_start_primary_key: ("PK1", INTEGER, 1)
      exclusive_end_primary_key: ("PK1", INTEGER, 4)
      columns_to_get: "PK1", "Attr1"
      
      //响应
      cosumed_read_capacity_unit: 1
      rows: {
            {
              primary_key_columns:("PK1", INTEGER, 1)
            },
            {
              primary_key_columns:("PK1", INTEGER, 2),
              attribute_columns:("Attr1", INTEGER, 8)
            },
            {
              primary_key_columns:("PK1", INTEGER, 3),
              attribute_columns:("Attr1", STRING, String(1000Byte))
            },
          }
                                  

使用

您可以使用如下语言的SDK实现基础数据操作。

最佳实践

详情请参见表格存储数据操作的最佳实践

计费

详情请参见计费概述

错误码

详情请参见错误码参考