写入数据

表格存储提供了单行插入、单行更新和批量写入的写入方式用于写入数据到数据表。当要写入数据到数据表时,您需要指定完整主键以及要增删改的属性列。在高并发应用中写入数据时,您可以配置行存在性条件或者列条件实现按照指定条件更新数据。

如果需要了解表格存储各场景的应用案例,请参见快速玩转Tablestore入门与实战

前提条件

插入单行数据

调用PutRow接口新写入一行数据。如果该行已存在,则先删除原行数据(原行的所有列以及所有版本的数据),再写入新行数据。

接口

/**
 * 写入一行数据。如果该行已存在,则先删除原行数据(原行的所有列以及所有版本的数据),再写入新行数据。返回该操作消耗的CU。
 * @api
 * @param [] $request 请求参数。
 * @return [] 请求返回。 
 * @throws OTSClientException 当参数检查出错或服务端返回校验出错时抛出异常。
 * @throws OTSServerException 当OTS服务端返回错误时抛出异常。
 */
public function putRow(array $request);            

请求信息

请求参数

参数

说明

table_name

数据表名称。

condition

使用条件更新,可以设置原行的存在性条件或者原行中某列的列值条件。更多信息,请参见条件更新

  • row_existence:行存在性条件。

    说明
    • RowExistenceExpectationConst::CONST_IGNORE表示无论此行是否存在均会插入新数据,如果之前行已存在,则写入数据时会覆盖原有数据。

    • RowExistenceExpectationConst::CONST_EXPECT_EXIST表示只有此行存在时才会插入新数据,写入数据时会覆盖原有数据。

    • RowExistenceExpectationConst::CONST_EXPECT_NOT_EXIST表示只有此行不存在时才会插入数据。

  • column_condition:列条件。

primary_key

行的主键。

说明
  • 设置的主键个数和类型必须和数据表的主键个数和类型一致。

  • 当主键为自增列时,只需将自增列的值设置为占位符。更多信息,请参见主键列自增

  • 数据表可包含1个~4个主键列。主键列是有顺序的,与用户添加的顺序相同,例如PRIMARY KEY(A, B, C)与PRIMARY KEY(A, C, B)是不同的两个主键结构。表格存储会按照主键的大小对行进行排序。

  • 每一项的顺序是主键名、主键值PrimaryKeyValue、主键类型PrimaryKeyType(可选)。

  • PrimaryKeyValue可以是整数、二进制和字符串。

  • PrimaryKeyType可以是INTEGER、STRING(UTF-8编码字符串)、BINARY、PK_AUTO_INCR(主键列自增)四种,分别用PrimaryKeyTypeConst::CONST_INTEGERPrimaryKeyTypeConst::CONST_STRINGPrimaryKeyTypeConst::CONST_BINARYPrimaryKeyTypeConst::CONST_PK_AUTO_INCR表示,对于INTEGERSTRING,可以省略,其它类型不可省略。

attribute_columns

行的属性列。

  • 每一项的顺序是属性名、属性值ColumnValue、属性类型ColumnType(可选)、时间戳(可选)。

  • ColumnType可以是INTEGER、STRING(UTF-8编码字符串)、BINARY、BOOLEAN、DOUBLE五种,分别用ColumnTypeConst::CONST_INTEGERColumnTypeConst::CONST_STRINGColumnTypeConst::CONST_BINARY、ColumnTypeConst::CONST_BOOLEANColumnTypeConst::CONST_DOUBLE表示,其中BINARY不可省略,其他类型都可以省略,或者设置为null。

  • 时间戳即数据的版本号。更多信息,请参见数据版本和生命周期

    数据的版本号可以由系统自动生成或者自定义,如果不设置此参数,则默认由系统自动生成。

    • 当由系统自动生成数据的版本号时,系统默认将当前时间的毫秒单位时间戳(从1970-01-01 00:00:00 UTC计算起的毫秒数)作为数据的版本号。

    • 当自定义数据的版本号时,版本号需要为64位的毫秒单位时间戳且在有效版本范围内。

return_content

表示返回类型。

return_type:设置为ReturnTypeConst::CONST_PK,表示返回主键值,主要用于主键列自增场景。

请求格式

$result = $client->putRow([
    'table_name' => '<string>', //设置数据表名称。
    'condition' => [
        'row_existence' => <RowExistence>,   
        'column_condition' => <ColumnCondition>
    ],
    'primary_key' => [                              //设置主键。
        ['<string>', <PrimaryKeyValue>], 
        ['<string>', <PrimaryKeyValue>],
        ['<string>', <PrimaryKeyValue>, <PrimaryKeyType>]
    ],  
    'attribute_columns' => [         //设置属性列。
            ['<string>', <ColumnValue>], 
            ['<string>', <ColumnValue>, <ColumnType>],
            ['<string>', <ColumnValue>, <ColumnType>, <integer>]
    ],
    'return_content' => [
        'return_type' => <ReturnType>
    ]
]);         

响应信息

响应参数

参数

说明

consumed

本次操作消耗服务能力单元的值。

capacity_unit表示使用的读写能力单元。

  • read:读吞吐量

  • write:写吞吐量

primary_key

主键的值,和请求时一致。

说明

当在请求中设置return_typeReturnTypeConst::CONST_PK时,会返回完整的主键,主要用于主键列自增。

attribute_columns

属性列的值,和请求时一致,目前为空。

响应格式

[
    'consumed' => [
        'capacity_unit' => [
            'read' => <integer>,
            'write' => <integer>
        ]
    ],
    'primary_key' => [ 
        ['<string>', <PrimaryKeyValue>], 
        ['<string>', <PrimaryKeyValue>],
        ['<string>', <PrimaryKeyValue>, <PrimaryKeyType>]
    ],  
    'attribute_columns' => []
]        

示例

插入数据时由系统自动生成数据版本号

以下示例用于写入10列属性列,每列写入1个版本,由系统自动生成数据的版本号(时间戳)。

$attr = array();
for($i = 0; $i < 10; $i++) {
    $attr[] = ['Col'. $i, $i]; 
}
$request = [
    'table_name' => 'MyTable',
    'condition' => RowExistenceExpectationConst::CONST_IGNORE, //condition可以为IGNORE、EXPECT_EXIST和EXPECT_NOT_EXIST。
    'primary_key' => [ //设置主键。
        ['PK0', 123],
        ['PK1', 'abc']
    ],
    'attribute_columns' => $attr
];
$response = $otsClient->putRow ($request);            

插入数据时自定义数据版本号

以下示例用于写入10列属性列,每列写入3个版本,自定义数据的版本号(时间戳)。

$attr = array();
$timestamp = getMicroTime();
for($i = 0; $i < 10; $i++) {
    for($j = 0; $j < 3; $j++) {
        $attr[] = ['Col'. $i, $j, null, $timestamp+$j];
    }
}
$request = [
    'table_name' => 'MyTable',
    'condition' => RowExistenceExpectationConst::CONST_IGNORE, //condition可以为IGNORE、EXPECT_EXIST和EXPECT_NOT_EXIST。
    'primary_key' => [ //设置主键。
        ['PK0', 123],
        ['PK1', 'abc']
    ],
    'attribute_columns' => $attr
];
$response = $otsClient->putRow ($request);            

插入数据时使用行条件

以下示例用于当原行不存在时,写入10列属性列,每列写入3个版本,自定义数据的版本号(时间戳)。

$attr = array();
$timestamp = getMicroTime();
for($i = 0; $i < 10; $i++) {
    for($j = 0; $j < 3; $j++) {
        $attr[] = ['Col'. $i, $j, null, $timestamp+$j];
    }
}
$request = [
    'table_name' => 'MyTable',
    'condition' => RowExistenceExpectationConst::CONST_EXPECT_NOT_EXIST, //设置期望原行不存在时,写入数据。
    'primary_key' => [ //设置主键。
        ['PK0', 123],
        ['PK1', 'abc']
    ],
    'attribute_columns' => $attr
];
$response = $otsClient->putRow ($request);            

插入数据时使用列条件和行条件

以下示例当原行存在且Col0列的值大于100时,写入10列属性列,每列写入3个版本,自定义数据的版本号(时间戳)。

$attr = array();
$timestamp = getMicroTime();
for($i = 0; $i < 10; $i++) {
    for($j = 0; $j < 3; $j++) {
        $attr[] = ['Col'. $i, $j, null, $timestamp+$j];
    }
}
$request = [
    'table_name' => 'MyTable',
    'condition' => [
        'row_existence' => RowExistenceExpectationConst::CONST_EXPECT_EXIST,//期望原行存在。
        'column_condition' => [                  //使用条件更新,满足条件则更新。
            'column_name' => 'Col0',
            'value' => 100,
            'comparator' => ComparatorTypeConst::CONST_GREATER_THAN
        ]
    ,
    'primary_key' => [ //设置主键。
        ['PK0', 123],
        ['PK1', 'abc']
    ],
    'attribute_columns' => $attr
];
$response = $otsClient->putRow ($request);           

更新单行数据

调用UpdateRow接口更新一行数据,可以增加和删除一行中的属性列,删除属性列指定版本的数据,或者更新已存在的属性列的值。如果更新的行不存在,则新增一行数据。

说明

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

接口

/**
 * 更新一行数据。
 * @api
 * @param [] $request 请求参数。
 * @return [] 请求返回。
 * @throws OTSClientException 当参数检查出错或服务端返回校验出错时抛出异常。
 * @throws OTSServerException 当OTS服务端返回错误时抛出异常。
 */
public function updateRow(array $request);            

请求信息

请求参数

参数

说明

table_name

数据表名称。

condition

使用条件更新,可以设置原行的存在性条件或者原行中某列的列值条件。更多信息,请参见条件更新

primary_key

行的主键。

重要

设置的主键个数和类型必须和数据表的主键个数和类型一致。

update_of_attribute_columns

更新的属性列。

  • 增加或更新数据时,需要设置属性名、属性值、属性类型(可选)、时间戳(可选)。

    属性名即属性列的名称,属性类型即属性列的数据类型。更多信息,请参见命名规则和数据类型

    时间戳即数据的版本号,可以由系统自动生成或者自定义,如果不设置此参数,则默认由系统自动生成。更多信息,请参见数据版本和生命周期

    • 当由系统自动生成数据的版本号时,系统默认将当前时间的毫秒单位时间戳(从1970-01-01 00:00:00 UTC计算起的毫秒数)作为数据的版本号。

    • 当自定义数据的版本号时,版本号需要为64位的毫秒单位时间戳且在有效版本范围内。

  • 删除属性列特定版本的数据时,只需要设置属性名和时间戳。

    时间戳是64位整数,单位为毫秒,表示某个特定版本的数据。

  • 删除属性列时,只需要设置属性名。

    说明

    删除一行的全部属性列不等同于删除该行,如果需要删除该行,请使用DeleteRow操作。

return_content

表示返回类型。

return_type:目前只需要设置为ReturnTypeConst::CONST_PK,表示返回主键值,主要用于主键列自增场景。

请求格式

$result = $client->updateRow([
    'table_name' => '<string>', //设置数据表名称。
    'condition' => [
        'row_existence' => <RowExistence>,
        'column_condition' => <ColumnCondition>
    ],
    'primary_key' => [                         //设置主键。
        ['<string>', <PrimaryKeyValue>], 
        ['<string>', <PrimaryKeyValue>],
        ['<string>', <PrimaryKeyValue>, <PrimaryKeyType>]
    ], 
    'update_of_attribute_columns' => [         //设置更新的属性列。
        'PUT' => [
            ['<string>', <ColumnValue>], 
            ['<string>', <ColumnValue>, <ColumnType>],
            ['<string>', <ColumnValue>, <ColumnType>, <integer>]
        ],
        'DELETE' => [
            ['<string>', <integer>], 
            ['<string>', <integer>], 
            ['<string>', <integer>], 
            ['<string>', <integer>]
        ],
        'DELETE_ALL' => [
            '<string>',
            '<string>',
            '<string>',
            '<string>'
        ],        
    ],
    'return_content' => [
        'return_type' => <ReturnType>
    ]
]);            

响应信息

响应参数

参数

说明

consumed

本次操作消耗服务能力单元的值。

capacity_unit表示使用的读写能力单元。

  • read:读吞吐量

  • write:写吞吐量

primary_key

主键的值,和请求时一致。

说明

当在请求中设置return_typeReturnTypeConst::CONST_PK时,会返回完整的主键,主要用于主键列自增。

attribute_columns

属性列的值,和请求时一致,目前为空。

结果格式

[
    'consumed' => [
        'capacity_unit' => [
            'read' => <integer>,
            'write' => <integer>
        ]
    ],
    'primary_key' => [ 
        ['<string>', <PrimaryKeyValue>], 
        ['<string>', <PrimaryKeyValue>],
        ['<string>', <PrimaryKeyValue>, <PrimaryKeyType>]
    ],  
    'attribute_columns' => []
]            

示例

更新数据时不使用条件

以下示例用于更新一些列,删除某列的某一版本,删除某列。

$request = [
    'table_name' => 'MyTable',
    'condition' => RowExistenceExpectationConst::CONST_IGNORE,
    'primary_key' => [ //设置主键。
        ['PK0', 123],
        ['PK1', 'abc']
    ],
    'update_of_attribute_columns' => [
        'PUT' => [                       //更新一些列。
            ['Col0', 100],
            ['Col1', 'Hello'],
            ['Col2', 'a binary', ColumnTypeConst::CONST_BINARY],
            ['Col3', 100, null, 1526418378526]
        ],
        'DELETE' => [                    //删除某列的某一版本。
            ['Col10', 1526418378526]
        ],
        'DELETE_ALL' => [
            'Col11'                      //删除某一列。
        ]
    ]
];
$response = $otsClient->updateRow($request);            

更新数据时使用列条件和行条件

以下示例用于当原行存在且Col0列的值大于100时更新数据。

$request = [
    'table_name' => 'MyTable',
    'primary_key' => [ //设置主键。
        ['PK0', 123],
        ['PK1', 'abc']
    ],
    'condition' => [
        'row_existence' => RowExistenceExpectationConst::CONST_EXPECT_EXIST, //期望原行存在。
        'column_filter' => [                                                 //当Col0列的值大于100时更新数据。
            'column_name' => 'Col0',
            'value' => 100,
            'comparator' => ComparatorTypeConst::CONST_GREATER_THAN
        ]
    ],    
    'update_of_attribute_columns' => [
        'PUT' => [                       //更新一些列。
            ['Col0', 100],
            ['Col1', 'Hello'],
            ['Col2', 'a binary', ColumnTypeConst::CONST_BINARY],
            ['Col3', 100, null, 1526418378526]
        ],
        'DELETE' => [                    //删除某列的某一版本。
            ['Col10', 1526418378526]
        ],
        'DELETE_ALL' => [
            'Col11'                      //删除某一列。
        ]
    ]
];         

批量写入数据

调用BatchWriteRow接口在一次请求中进行批量写入操作或者一次对多张表进行写入。

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

注意事项

由于批量写入可能存在部分行失败的情况,失败行的Index及错误信息在返回的BatchWriteRowResponse中,但并不抛出异常。因此调用BatchWriteRow接口时,需要检查返回值,判断每行的状态是否成功;如果不检查返回值,则可能会忽略掉部分操作的失败。

当服务端检查到某些操作出现参数错误时,BatchWriteRow接口可能会抛出参数错误的异常,此时该请求中所有的操作都未执行。

接口

/**
 * 写入、更新或者删除指定的多行数据。
 * 请注意BatchWriteRow在部分行写入失败时,会在返回的$response中表示,而不是抛出异常。更多信息,请参见处理BatchWriteRow的返回样例。
 * @api
 * @param [] $request 请求参数。
 * @return [] 请求返回。
 * @throws OTSClientException 当参数检查出错或服务端返回校验出错时。
 * @throws OTSServerException 当OTS服务端返回错误时。
 */
public function batchWriteRow(array $request);              

请求信息

请求参数

本操作是PutRow、UpdateRow、DeleteRow的组合。

  • 增加了数据表的层级结构,可以一次处理多个数据表。

    tables以数据表为单位组织,后续为各个数据表的操作,设置需要写入、修改或删除的行信息。

  • 增加了operation_type参数,用于区分操作类型。

    操作类型可以为PUT、UPDATE、DELETE,分别用OperationTypeConst::CONST_PUT、OperationTypeConst::CONST_UPDATE、OperationTypeConst::CONST_DELETE表示。

    • 当操作类型为PUT时,primary_keyattribute_columns有效。

    • 当操作类型为UPDATE时,primary_keyupdate_of_attribute_columns有效。

    • 当操作类型为DELETE时,primary_key有效。

请求格式

$result = $client->batchWriteRow([
    'tables' => [                                            //设置数据表的层级结构。
        [
            'table_name' => '<string>',                      //设置数据表名称。
            'operation_type' => <OperationType>,
            'condition' => [
                'row_existence' => <RowExistence>,   
                'column_condition' => <ColumnCondition>
            ],
            'primary_key' => [                               //设置主键。
                ['<string>', <PrimaryKeyValue>], 
                ['<string>', <PrimaryKeyValue>],
                ['<string>', <PrimaryKeyValue>, <PrimaryKeyType>]
            ], 
            'attribute_columns' => [                        //当操作类型为PUT时必须设置。
                    ['<string>', <ColumnValue>], 
                    ['<string>', <ColumnValue>, <ColumnType>],
                    ['<string>', <ColumnValue>, <ColumnType>, <integer>]
            ],
            'update_of_attribute_columns' => [               //当操作类型为UPDATE时必须设置。
                'PUT' => [
                    ['<string>', <ColumnValue>], 
                    ['<string>', <ColumnValue>, <ColumnType>],
                    ['<string>', <ColumnValue>, <ColumnType>, <integer>]
                ],
                'DELETE' => [
                    ['<string>', <integer>], 
                    ['<string>', <integer>], 
                    ['<string>', <integer>], 
                    ['<string>', <integer>]
                ],
                'DELETE_ALL' => [
                    '<string>',
                    '<string>',
                    '<string>',
                    '<string>'
                ],
            ],
            'return_content' => [
                'return_type' => <ReturnType>
            ]
        ],
        //其他数据表。
    ]
]);        

响应信息

响应参数

tablestable为单位组织,和请求一一对应,参数说明请参见下表。

参数

说明

table_name

数据表名称。

is_ok

该行操作是否成功。

  • 如果值为true,则该行写入成功,此时error无效。

  • 如果值为false,则该行写入失败。

error

用于在操作失败时的响应消息中表示错误信息。

  • code表示当前单行操作的错误码。

  • message表示当前单行操作的错误信息。

consumed

本次操作消耗服务能力单元的值。

capacity_unit表示使用的读写单元。

  • read:读吞吐量

  • write:写吞吐量

primary_key

主键的值,和请求时一致。

设置return_type时会有值,主要用于主键列自增。

attribute_columns

属性列的值,和请求时一致,目前为空。

结果格式

[
    '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' => []
                ],
                //其他行。
            ]
        ],
        //其他数据表。
    ]
]           

示例

以下示例用于批量写入30行数据,分别向3个数据表中写入数据,每个数据表中写入10行。

//向3个数据表中写入数据,每个数据表中写入10行。
$tables = array();
for($i = 0; $i < 3; $i++) {
    $rows = array();
    for($j = 0; $j < 10; $j++) {
        $rows[] = [
            'operation_type' => OperationTypeConst::CONST_PUT, //设置操作类型为PUT。
            'condition' => RowExistenceExpectationConst::CONST_IGNORE,
            'primary_key' => [
                ['pk0', $i],
                ['pk1', $j]
            ],
            'attribute_columns' => [
                ['Col0', 4],
                ['Col2', '成杭京']
            ]
        ];
    }
    $tables[] = [
        'table_name' => 'SampleTable' . $i,
        'rows' => $rows
    ];
}
$request = [
    'tables' => $tables
];
$response = $otsClient->batchWriteRow ($request);
//处理返回的每个数据表。
foreach ($response['tables'] as $tableData) {
  print "Handling table {$tableData['table_name']} ...\n";

  //处理该数据表下的PutRow返回的结果。
  $putRows = $tableData['rows'];

  foreach ($putRows as $rowData) {

    if ($rowData['is_ok']) {
      //写入成功。
      print "Capacity Unit Consumed: {$rowData['consumed']['capacity_unit']['write']}\n";
    } else {

      //处理出错。
      print "Error: {$rowData['error']['code']} {$rowData['error']['message']}\n";
    }
  }
}           

详细代码示例请参见下表。

示例

说明

BatchWriteRow1.php

展示了BatchWriteRow中多个PUT的用法。

BatchWriteRow2.php

展示了BatchWriteRow中多个UPDATE的用法。

BatchWriteRow3.php

展示了BatchWriteRow中多个DELETE的用法。

BatchWriteRow4.php

展示了BatchWriteRow中组合使用UPDATE、PUTDELETE的用法。

BatchWriteRowWithColumnFilter.php

展示了BatchWriteRow中同时使用条件更新的用法。

常见问题

相关文档

  • 当要在高并发应用中实现按照指定条件更新数据时,您可以通过条件更新实现。更多信息,请参见条件更新

  • 当要为在线应用提供实时统计功能时,例如统计帖子的PV(实时浏览量)等,您可以通过原子计数器实现。更多信息,请参见原子计数器

  • 当要进行单行写或多行写的原子操作,您可以通过局部事务实现。更多信息,请参见局部事务

  • 写入数据后,即可根据需要读取或者删除表中数据。更多信息,请参见读取数据删除数据