- DynamoDB 教程
- DynamoDB - 主页
- DynamoDB - 概述
- DynamoDB - 基本概念
- DynamoDB - 环境
- DynamoDB - 操作工具
- DynamoDB - 数据类型
- DynamoDB - 创建表
- DynamoDB - 加载表
- DynamoDB - 查询表
- DynamoDB - 删除表
- DynamoDB - API 接口
- DynamoDB - 创建项目
- DynamoDB - 获取项目
- DynamoDB - 更新项目
- DynamoDB - 删除项目
- DynamoDB - 批量写入
- DynamoDB - 批量检索
- DynamoDB - 查询
- DynamoDB - 扫描
- DynamoDB - 索引
- 全球二级指数
- 本地二级索引
- DynamoDB - 聚合
- DynamoDB - 访问控制
- DynamoDB - 权限 API
- DynamoDB - 条件
- 网络身份联合
- DynamoDB - 数据管道
- DynamoDB - 数据备份
- DynamoDB - 监控
- DynamoDB - CloudTrail
- DynamoDB-MapReduce
- DynamoDB - 表活动
- DynamoDB - 错误处理
- DynamoDB - 最佳实践
- DynamoDB 有用资源
- DynamoDB - 快速指南
- DynamoDB - 有用的资源
- DynamoDB - 讨论
DynamoDB - 快速指南
DynamoDB - 概述
DynamoDB 允许用户创建能够存储和检索任意数量的数据并服务任意数量的流量的数据库。它自动在服务器上分配数据和流量,以动态管理每个客户的请求,并保持快速性能。
DynamoDB 与 RDBMS
DynamoDB 使用 NoSQL 模型,这意味着它使用非关系系统。下表突出显示了 DynamoDB 和 RDBMS 之间的差异 -
常见任务 | 关系型数据库管理系统 | 动态数据库 |
---|---|---|
连接到源 | 它使用持久连接和 SQL 命令。 | 它使用HTTP请求和API操作 |
创建一个表 | 它的基本结构是表,并且必须被定义。 | 它仅使用主键,并且在创建时不使用模式。它使用各种数据源。 |
获取餐桌信息 | 所有表格信息仍然可访问 | 仅显示主键。 |
加载表数据 | 它使用由列组成的行。 | 在表中,它使用由属性组成的项目 |
读取表数据 | 它使用 SELECT 语句和过滤语句。 | 它使用 GetItem、Query 和 Scan。 |
管理索引 | 它使用通过 SQL 语句创建的标准索引。表更改时会自动对其进行修改。 | 它使用二级索引来实现相同的功能。它需要规范(分区键和排序键)。 |
修改表数据 | 它使用 UPDATE 语句。 | 它使用 UpdateItem 操作。 |
删除表数据 | 它使用 DELETE 语句。 | 它使用DeleteItem 操作。 |
删除表 | 它使用 DROP TABLE 语句。 | 它使用DeleteTable 操作。 |
优点
DynamoDB 的两个主要优势是可扩展性和灵活性。它不强制使用特定的数据源和结构,允许用户以统一的方式使用几乎任何东西。
其设计还支持广泛的使用,从较轻的任务和操作到要求较高的企业功能。它还允许简单地使用多种语言:Ruby、Java、Python、C#、Erlang、PHP 和 Perl。
局限性
DynamoDB 确实存在某些限制,但是,这些限制并不一定会造成巨大的问题或阻碍稳健的发展。
您可以从以下几点回顾它们 -
容量单位大小- 读取容量单位是每秒对不大于 4KB 的项目进行的一次一致读取。写入容量单位是每秒写入不大于 1KB 的项目。
预配置吞吐量最小值/最大值- 所有表和全局二级索引至少具有 1 个读取和 1 个写入容量单位。最大值取决于地区。在美国,每张表的读写上限仍然是 40K(每个账户 80K),其他地区的每张表的上限为 10K,账户上限为 20K。
预置吞吐量增加和减少- 您可以根据需要增加此数量,但减少量仍限制为每个表每天不超过四次。
每个账户的牌桌大小和数量- 牌桌大小没有限制,但账户有 256 个牌桌限制,除非您请求更高的上限。
每表二级索引- 允许五个本地索引和五个全局索引。
每个表的预计二级索引属性- DynamoDB 允许 20 个属性。
分区键长度和值- 它们的最小长度为 1 字节,最大长度为 2048 字节,但是,DynamoDB 对值没有限制。
排序键长度和值- 其最小长度为 1 字节,最大长度为 1024 字节,值没有限制,除非其表使用本地二级索引。
表和二级索引名称- 名称的长度必须至少为 3 个字符,最多为 255 个字符。它们使用以下字符:AZ、az、0-9、“_”、“-”和“.” 。
属性名称- 最小为 1 个字符,最大为 64KB,键和某些属性除外。
保留字- DynamoDB 不会阻止使用保留字作为名称。
表达式长度- 表达式字符串有 4KB 限制。属性表达式有 255 字节的限制。表达式的替换变量有 2MB 限制。
DynamoDB - 基本概念
在使用DynamoDB之前,您必须熟悉其基本组件和生态系统。在 DynamoDB 生态系统中,您使用表、属性和项目。表保存项目集,项目保存属性集。属性是不需要进一步分解的数据的基本元素,即字段。
首要的关键
主键作为表项的唯一标识手段,二级索引提供查询灵活性。DynamoDB 流通过修改表数据来记录事件。
创建表不仅需要设置名称,还需要设置主键;它标识表项。没有两个项目共享一个密钥。DynamoDB 使用两种类型的主键 -
分区键- 这个简单的主键由一个称为“分区键”的属性组成。在内部,DynamoDB 使用键值作为哈希函数的输入来确定存储。
分区键和排序键- 该键称为“复合主键”,由两个属性组成。
分区键和
排序键。
DynamoDB 将第一个属性应用于哈希函数,并将具有相同分区键的项目存储在一起;它们的顺序由排序键确定。项目可以共享分区键,但不能共享排序键。
主键属性仅允许标量(单个)值;以及字符串、数字或二进制数据类型。非键属性没有这些约束。
二级索引
这些索引允许您使用备用键查询表数据。尽管 DynamoDB 不强制使用它们,但它们优化了查询。
DynamoDB 使用两种类型的二级索引 -
全局二级索引- 该索引拥有分区键和排序键,它们可以与表键不同。
本地二级索引- 该索引拥有与表相同的分区键,但其排序键不同。
应用程序编程接口
DynamoDB 提供的 API 操作包括控制平面、数据平面(例如创建、读取、更新和删除)和流的 API 操作。在控制平面操作中,您可以使用以下工具创建和管理表 -
- 创建表
- 描述表
- 列表表
- 更新表
- 删除表
在数据平面中,您可以使用以下工具执行 CRUD 操作 -
创造 | 读 | 更新 | 删除 |
---|---|---|---|
放置项目 批量写入项目 |
获取项目 批量获取项目 询问 扫描 |
更新项目 | 删除项目 批量写入项目 |
流操作控制表流。您可以查看以下流工具 -
- 列表流
- 描述流
- 获取分片迭代器
- 获取记录
预置吞吐量
在表创建过程中,您可以指定预置吞吐量,这会预留用于读取和写入的资源。您可以使用容量单位来测量和设置吞吐量。
当应用程序超过设定的吞吐量时,请求将失败。DynamoDB GUI 控制台允许监控设置和使用的吞吐量,以实现更好的动态配置。
读取一致性
DynamoDB 使用最终一致和强一致性读取来支持动态应用程序需求。最终一致的读取并不总是提供当前数据。
强一致性读取始终提供当前数据(设备故障或网络问题除外)。最终一致性读取作为默认设置,需要在ConcientRead参数中设置 true才能更改它。
分区
DynamoDB 使用分区进行数据存储。表的这些存储分配有 SSD 支持并自动跨区域复制。DynamoDB 管理所有分区任务,无需用户参与。
创建表时,表进入CREATING状态,分配分区。当它达到ACTIVE状态时,您可以执行操作。当系统容量达到最大值或更改吞吐量时,系统会更改分区。
DynamoDB - 环境
DynamoDB 环境仅包括使用您的 Amazon Web Services 帐户访问 DynamoDB GUI 控制台,但是您也可以执行本地安装。
导航到以下网站 - https://aws.amazon.com/dynamodb/
单击“开始使用 Amazon DynamoDB”按钮,如果您没有 Amazon Web Services 帐户,则单击“创建 AWS 帐户”按钮。简单的引导流程将告知您所有相关费用和要求。
执行该过程的所有必要步骤后,您将获得访问权限。只需登录 AWS 控制台,然后导航到 DynamoDB 控制台即可。
请务必删除未使用或不必要的材料,以避免产生相关费用。
本地安装
AWS(Amazon Web Service)提供了一个用于本地安装的 DynamoDB 版本。它支持在没有 Web 服务或连接的情况下创建应用程序。它还通过允许本地数据库来降低预配置吞吐量、数据存储和传输费用。本指南假设本地安装。
准备好部署后,您可以对应用程序进行一些小调整,以将其转换为 AWS 使用。
安装文件是一个.jar 可执行文件。它可以在 Linux、Unix、Windows 和任何其他支持 Java 的操作系统中运行。使用以下链接之一下载文件 -
压缩包- http://dynamodb-local.s3-website-us-west2.amazonaws.com/dynamodb_local_latest.tar.gz
Zip 存档- http://dynamodb-local.s3-website-us-west2.amazonaws.com/dynamodb_local_latest.zip
注意- 其他存储库提供该文件,但不一定是最新版本。使用上面的链接获取最新的安装文件。另外,请确保您拥有 Java 运行时引擎 (JRE) 版本 6.x 或更高版本。DynamoDB 无法与旧版本一起运行。
下载适当的存档后,解压其目录 (DynamoDBLocal.jar) 并将其放置在所需位置。
然后,您可以通过打开命令提示符、导航到包含 DynamoDBLocal.jar 的目录并输入以下命令来启动 DynamoDB -
java -Djava.library.path=./DynamoDBLocal_lib -jar DynamoDBLocal.jar -sharedDb
您还可以通过关闭用于启动 DynamoDB 的命令提示符来停止 DynamoDB。
工作环境
您可以使用 JavaScript shell、GUI 控制台和多种语言来使用 DynamoDB。可用的语言包括 Ruby、Java、Python、C#、Erlang、PHP 和 Perl。
在本教程中,为了概念和代码的清晰性,我们使用 Java 和 GUI 控制台示例。安装 Java IDE、适用于 Java 的 AWS 开发工具包,并为 Java 开发工具包设置 AWS 安全凭证以便使用 Java。
从本地到 Web 服务代码的转换
准备好部署后,您将需要更改代码。调整取决于代码语言和其他因素。主要更改仅包括将终端节点从本地点更改为 AWS 区域。其他更改需要对您的应用程序进行更深入的分析。
本地安装在很多方面与 Web 服务不同,包括但不限于以下主要区别 -
本地安装会立即创建表,但服务需要更长的时间。
本地安装忽略吞吐量。
删除会在本地安装中立即发生。
由于没有网络开销,本地安装中的读/写速度很快。
DynamoDB - 操作工具
DynamoDB 提供了三种执行操作的选项:基于 Web 的 GUI 控制台、JavaScript shell 和您选择的编程语言。
在本教程中,我们将重点介绍如何使用 GUI 控制台和 Java 语言,以实现清晰度和概念理解。
图形用户界面控制台
GUI 控制台或适用于 Amazon DynamoDB 的 AWS 管理控制台可在以下地址找到 - https://console.aws.amazon.com/dynamodb/home
它允许您执行以下任务 -
- 增删改查
- 查看表项目
- 执行表查询
- 设置表容量监控警报
- 实时查看表指标
- 查看表警报
如果您的 DynamoDB 账户没有表,则在访问时,它会指导您创建表。它的主屏幕提供了三个用于执行常见操作的快捷方式 -
- 创建表
- 添加和查询表
- 监控和管理表
JavaScript 外壳
DynamoDB 包含一个交互式 JavaScript shell。shell 在 Web 浏览器内运行,推荐的浏览器包括 Firefox 和 Chrome。
注意- 使用其他浏览器可能会导致错误。
通过打开 Web 浏览器并输入以下地址来访问 shell - http://localhost:8000/shell
通过在左侧窗格中输入 JavaScript 来使用 shell,然后单击左侧窗格右上角的“Play”图标按钮来运行代码。代码结果显示在右侧窗格中。
DynamoDB 和 Java
利用 Java 开发环境将 Java 与 DynamoDB 结合使用。操作符合正常的 Java 语法和结构。
DynamoDB - 数据类型
DynamoDB 支持的数据类型包括特定于属性、操作和您选择的编码语言的数据类型。
属性数据类型
DynamoDB 支持大量表属性数据类型。每种数据类型属于以下三个类别之一 -
标量- 这些类型表示单个值,包括数字、字符串、二进制、布尔值和 null。
文档- 这些类型表示具有嵌套属性的复杂结构,包括列表和映射。
集- 这些类型表示多个标量,包括字符串集、数字集和二进制集。
请记住,DynamoDB 是一种无架构、NoSQL 数据库,在创建表时不需要属性或数据类型定义。与 RDBMS 不同,它只需要主键属性数据类型,而 RDBMS 在创建表时需要列数据类型。
标量
数字- 限制为 38 位数字,并且可以是正数、负数或零。
字符串- 它们是使用 UTF-8 的 Unicode,最小长度 >0,最大长度 400KB。
二进制- 它们存储任何二进制数据,例如加密数据、图像和压缩文本。DynamoDB 将其字节视为无符号。
布尔值- 它们存储 true 或 false。
Null - 它们代表未知或未定义的状态。
文档
列表- 它存储有序值集合,并使用方括号([...])。
Map - 它存储无序的名称-值对集合,并使用大括号({...})。
放
集合必须包含相同类型的元素,无论是数字、字符串还是二进制。对集合的唯一限制包括 400KB 项目大小限制,并且每个元素都是唯一的。
操作数据类型
DynamoDB API 保存操作使用的各种数据类型。您可以查看以下关键类型的选择 -
AttributeDefinition - 它表示键表和索引模式。
容量- 它表示表或索引消耗的吞吐量。
CreateGlobalSecondaryIndexAction - 它表示添加到表中的新全局二级索引。
LocalSecondaryIndex - 它表示本地二级索引属性。
ProvisionedThroughput - 它表示索引或表的预配置吞吐量。
PutRequest - 它代表 PutItem 请求。
TableDescription - 它表示表属性。
支持的 Java 数据类型
DynamoDB 为 Java 提供对原始数据类型、Set 集合和任意类型的支持。
DynamoDB - 创建表
创建表通常包括生成表、命名表、建立其主键属性以及设置属性数据类型。
利用 GUI 控制台、Java 或其他选项来执行这些任务。
使用 GUI 控制台创建表
通过访问控制台https://console.aws.amazon.com/dynamodb来创建表。然后选择“创建表”选项。
我们的示例生成一个填充有产品信息的表,其中的产品具有由 ID 号(数字属性)标识的唯一属性。在创建表屏幕中,在表名称字段中输入表名称;在分区键字段中输入主键 (ID);并输入“数字”作为数据类型。
输入所有信息后,选择“创建”。
使用Java创建表
使用 Java 创建相同的表。它的主键由以下两个属性组成 -
ID - 使用分区键和 ScalarAttributeType N,表示数字。
命名法- 使用排序键和 ScalarAttributeType S,表示字符串。
Java使用createTable方法生成表;在调用中,指定表名、主键属性和属性数据类型。
您可以查看以下示例 -
import java.util.Arrays; import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient; import com.amazonaws.services.dynamodbv2.document.DynamoDB; import com.amazonaws.services.dynamodbv2.document.Table; import com.amazonaws.services.dynamodbv2.model.AttributeDefinition; import com.amazonaws.services.dynamodbv2.model.KeySchemaElement; import com.amazonaws.services.dynamodbv2.model.KeyType; import com.amazonaws.services.dynamodbv2.model.ProvisionedThroughput; import com.amazonaws.services.dynamodbv2.model.ScalarAttributeType; public class ProductsCreateTable { public static void main(String[] args) throws Exception { AmazonDynamoDBClient client = new AmazonDynamoDBClient() .withEndpoint("http://localhost:8000"); DynamoDB dynamoDB = new DynamoDB(client); String tableName = "Products"; try { System.out.println("Creating the table, wait..."); Table table = dynamoDB.createTable (tableName, Arrays.asList ( new KeySchemaElement("ID", KeyType.HASH), // the partition key // the sort key new KeySchemaElement("Nomenclature", KeyType.RANGE) ), Arrays.asList ( new AttributeDefinition("ID", ScalarAttributeType.N), new AttributeDefinition("Nomenclature", ScalarAttributeType.S) ), new ProvisionedThroughput(10L, 10L) ); table.waitForActive(); System.out.println("Table created successfully. Status: " + table.getDescription().getTableStatus()); } catch (Exception e) { System.err.println("Cannot create the table: "); System.err.println(e.getMessage()); } } }
在上面的示例中,请注意端点:.withEndpoint。
它表示使用 localhost 进行本地安装。另请注意所需的ProvisionedThroughput 参数,本地安装会忽略该参数。
DynamoDB - 加载表
加载表通常包括创建源文件、确保源文件符合与 DynamoDB 兼容的语法、将源文件发送到目标,然后确认填充成功。
利用 GUI 控制台、Java 或其他选项来执行任务。
使用 GUI 控制台加载表
使用命令行和控制台的组合加载数据。您可以通过多种方式加载数据,其中一些方式如下 -
- 控制台
- 命令行
- 代码还有
- 数据管道(本教程稍后讨论的功能)
但是,为了提高速度,此示例同时使用 shell 和控制台。首先,使用以下语法将源数据加载到目标中 -
aws dynamodb batch-write-item -–request-items file://[filename]
例如 -
aws dynamodb batch-write-item -–request-items file://MyProductData.json
通过访问控制台来验证操作是否成功 -
https://console.aws.amazon.com/dynamodb
在导航栏中选择“表”,然后从表列表中选择目标表。
选择“项目”选项卡以检查用于填充表的数据。选择取消返回表列表。
使用 Java 加载表
首先创建源文件来使用 Java。我们的源文件使用 JSON 格式。每个产品都有两个主键属性(ID 和 Nomenclature)和一个 JSON 映射(Stat) -
[ { "ID" : ... , "Nomenclature" : ... , "Stat" : { ... } }, { "ID" : ... , "Nomenclature" : ... , "Stat" : { ... } }, ... ]
您可以查看以下示例 -
{ "ID" : 122, "Nomenclature" : "Particle Blaster 5000", "Stat" : { "Manufacturer" : "XYZ Inc.", "sales" : "1M+", "quantity" : 500, "img_src" : "http://www.xyz.com/manuals/particleblaster5000.jpg", "description" : "A laser cutter used in plastic manufacturing." } }
下一步是将文件放置在应用程序使用的目录中。
Java 主要使用putItem和path 方法来执行加载。
您可以查看以下代码示例来处理文件并加载它 -
import java.io.File; import java.util.Iterator; import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient; import com.amazonaws.services.dynamodbv2.document.DynamoDB; import com.amazonaws.services.dynamodbv2.document.Item; import com.amazonaws.services.dynamodbv2.document.Table; import com.fasterxml.jackson.core.JsonFactory; import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper import com.fasterxml.jackson.databind.node.ObjectNode; public class ProductsLoadData { public static void main(String[] args) throws Exception { AmazonDynamoDBClient client = new AmazonDynamoDBClient() .withEndpoint("http://localhost:8000"); DynamoDB dynamoDB = new DynamoDB(client); Table table = dynamoDB.getTable("Products"); JsonParser parser = new JsonFactory() .createParser(new File("productinfo.json")); JsonNode rootNode = new ObjectMapper().readTree(parser); Iterator<JsonNode> iter = rootNode.iterator(); ObjectNode currentNode; while (iter.hasNext()) { currentNode = (ObjectNode) iter.next(); int ID = currentNode.path("ID").asInt(); String Nomenclature = currentNode.path("Nomenclature").asText(); try { table.putItem(new Item() .withPrimaryKey("ID", ID, "Nomenclature", Nomenclature) .withJSON("Stat", currentNode.path("Stat").toString())); System.out.println("Successful load: " + ID + " " + Nomenclature); } catch (Exception e) { System.err.println("Cannot add product: " + ID + " " + Nomenclature); System.err.println(e.getMessage()); break; } } parser.close(); } }
DynamoDB - 查询表
查询表主要需要选择表、指定分区键、执行查询;可以选择使用二级索引并通过扫描操作执行更深入的过滤。
利用 GUI 控制台、Java 或其他选项来执行任务。
使用 GUI 控制台查询表
使用之前创建的表执行一些简单的查询。首先,打开控制台https://console.aws.amazon.com/dynamodb
从导航窗格中选择“表” ,然后从表列表中选择“回复” 。然后选择“项目”选项卡以查看加载的数据。
选择“创建项目”按钮下方的数据过滤链接(“扫描:[表]回复”)。
在过滤屏幕中,选择操作的查询。输入适当的分区键值,然后单击“开始”。
然后回复表返回匹配的项目。
使用Java查询表
使用Java中的查询方法来执行数据检索操作。它需要指定分区键值,排序键是可选的。
首先创建一个描述参数的querySpec 对象来编写 Java 查询。然后将对象传递给查询方法。我们使用前面示例中的分区键。
您可以查看以下示例 -
import java.util.HashMap; import java.util.Iterator; import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient; import com.amazonaws.services.dynamodbv2.document.DynamoDB; import com.amazonaws.services.dynamodbv2.document.Item; import com.amazonaws.services.dynamodbv2.document.ItemCollection; import com.amazonaws.services.dynamodbv2.document.QueryOutcome; import com.amazonaws.services.dynamodbv2.document.Table; import com.amazonaws.services.dynamodbv2.document.spec.QuerySpec; import com.amazonaws.services.dynamodbv2.document.utils.NameMap; public class ProductsQuery { public static void main(String[] args) throws Exception { AmazonDynamoDBClient client = new AmazonDynamoDBClient() .withEndpoint("http://localhost:8000"); DynamoDB dynamoDB = new DynamoDB(client); Table table = dynamoDB.getTable("Products"); HashMap<String, String> nameMap = new HashMap<String, String>(); nameMap.put("#ID", "ID"); HashMap<String, Object> valueMap = new HashMap<String, Object>(); valueMap.put(":xxx", 122); QuerySpec querySpec = new QuerySpec() .withKeyConditionExpression("#ID = :xxx") .withNameMap(new NameMap().with("#ID", "ID")) .withValueMap(valueMap); ItemCollection<QueryOutcome> items = null; Iterator<Item> iterator = null; Item item = null; try { System.out.println("Product with the ID 122"); items = table.query(querySpec); iterator = items.iterator(); while (iterator.hasNext()) { item = iterator.next(); System.out.println(item.getNumber("ID") + ": " + item.getString("Nomenclature")); } } catch (Exception e) { System.err.println("Cannot find products with the ID number 122"); System.err.println(e.getMessage()); } } }
请注意,查询使用分区键,但是二级索引为查询提供了另一种选择。它们的灵活性允许查询非关键属性,这个主题将在本教程后面讨论。
scan 方法还支持通过收集所有表数据进行检索操作。可选的 .withFilterExpression可防止指定条件之外的项目出现在结果中。
在本教程的后面部分,我们将详细讨论扫描。现在,看看下面的例子 -
import java.util.Iterator; import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient; import com.amazonaws.services.dynamodbv2.document.DynamoDB; import com.amazonaws.services.dynamodbv2.document.Item; import com.amazonaws.services.dynamodbv2.document.ItemCollection; import com.amazonaws.services.dynamodbv2.document.ScanOutcome; import com.amazonaws.services.dynamodbv2.document.Table; import com.amazonaws.services.dynamodbv2.document.spec.ScanSpec; import com.amazonaws.services.dynamodbv2.document.utils.NameMap; import com.amazonaws.services.dynamodbv2.document.utils.ValueMap; public class ProductsScan { public static void main(String[] args) throws Exception { AmazonDynamoDBClient client = new AmazonDynamoDBClient() .withEndpoint("http://localhost:8000"); DynamoDB dynamoDB = new DynamoDB(client); Table table = dynamoDB.getTable("Products"); ScanSpec scanSpec = new ScanSpec() .withProjectionExpression("#ID, Nomenclature , stat.sales") .withFilterExpression("#ID between :start_id and :end_id") .withNameMap(new NameMap().with("#ID", "ID")) .withValueMap(new ValueMap().withNumber(":start_id", 120) .withNumber(":end_id", 129)); try { ItemCollection<ScanOutcome> items = table.scan(scanSpec); Iterator<Item> iter = items.iterator(); while (iter.hasNext()) { Item item = iter.next(); System.out.println(item.toString()); } } catch (Exception e) { System.err.println("Cannot perform a table scan:"); System.err.println(e.getMessage()); } } }
DynamoDB - 删除表
在本章中,我们将讨论如何删除表以及删除表的不同方法。
表删除是一个简单的操作,只需要表名即可。利用 GUI 控制台、Java 或任何其他选项来执行此任务。
使用 GUI 控制台删除表
首先访问控制台来执行删除操作 -
https://console.aws.amazon.com/dynamodb。
从导航窗格中选择“表”,然后从表列表中选择要删除的表,如下屏幕截图所示。
最后,选择删除表。选择删除表后,会出现确认信息。然后您的表将被删除。
使用Java删除表
使用delete方法删除表。下面给出一个例子来更好地解释这个概念。
import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient; import com.amazonaws.services.dynamodbv2.document.DynamoDB; import com.amazonaws.services.dynamodbv2.document.Table; public class ProductsDeleteTable { public static void main(String[] args) throws Exception { AmazonDynamoDBClient client = new AmazonDynamoDBClient() .withEndpoint("http://localhost:8000"); DynamoDB dynamoDB = new DynamoDB(client); Table table = dynamoDB.getTable("Products"); try { System.out.println("Performing table delete, wait..."); table.delete(); table.waitForDelete(); System.out.print("Table successfully deleted."); } catch (Exception e) { System.err.println("Cannot perform table delete: "); System.err.println(e.getMessage()); } } }
DynamoDB - API 接口
DynamoDB 提供了一系列强大的 API 工具,用于表操作、数据读取和数据修改。
Amazon 建议使用AWS SDK(例如Java SDK)而不是调用低级API。这些库使得无需直接与低级 API 进行交互。这些库简化了常见任务,例如身份验证、序列化和连接。
操作表格
DynamoDB 为表管理提供了五种低级操作 -
CreateTable - 这会生成一个表并包括用户设置的吞吐量。它要求您设置主键,无论是复合主键还是简单主键。它还允许一个或多个二级索引。
ListTables - 这提供了当前 AWS 用户帐户中并与其端点绑定的所有表的列表。
UpdateTable - 这会改变吞吐量和全局二级索引吞吐量。
DescribeTable - 提供表元数据;例如,状态、大小和索引。
DeleteTable - 这只是删除表及其索引。
读取数据
DynamoDB 提供了四种用于数据读取的低级操作 -
GetItem - 它接受主键并返回关联项的属性。它允许更改其默认的最终一致读取设置。
BatchGetItem - 它通过主键对多个项目执行多个 GetItem 请求,可以选择一个或多个表。它返回的项目不超过 100 个,并且大小必须保持在 16MB 以下。它允许最终一致和强一致的读取。
扫描- 它读取所有表项并生成最终一致的结果集。您可以通过条件过滤结果。它避免使用索引并扫描整个表,因此不要将其用于需要可预测性的查询。
查询- 它返回单个或多个表项或二级索引项。它使用指定的分区键值,并允许使用比较运算符来缩小范围。它支持两种类型的一致性,并且每个响应都遵守 1MB 的大小限制。
修改数据
DynamoDB 提供了四种用于数据修改的低级操作 -
PutItem - 这会产生一个新项目或替换现有项目。默认情况下,发现相同的主键时,它会替换该项目。条件运算符允许您解决默认情况,并且仅在特定条件下替换项目。
BatchWriteItem - 这会执行多个 PutItem 和 DeleteItem 请求以及多个表。如果一个请求失败,不会影响整个操作。其上限为 25 个项目,大小为 16MB。
UpdateItem - 它更改现有项目属性,并允许使用条件运算符仅在某些条件下执行更新。
DeleteItem - 它使用主键来删除项目,还允许使用条件运算符来指定删除条件。
DynamoDB - 创建项目
在 DynamoDB 中创建项目主要包括项目和属性规范以及指定条件的选项。每个项目都作为一组属性存在,每个属性都被命名并分配了特定类型的值。
值类型包括标量、文档或集合。项目的大小限制为 400KB,任何数量的属性都可能符合该限制。名称和值大小(二进制和 UTF-8 长度)决定项目大小。使用短属性名称有助于最小化项目大小。
注意- 您必须指定所有主键属性,主键只需要分区键;以及需要分区键和排序键的复合键。
另外,请记住表没有预定义的模式。您可以在一张表中存储截然不同的数据集。
使用 GUI 控制台、Java 或其他工具来执行此任务。
如何使用 GUI 控制台创建项目?
导航到控制台。在左侧导航窗格中,选择“表格”。选择用作目标的表名称,然后选择“项目”选项卡,如以下屏幕截图所示。
选择创建项目。创建项目屏幕提供了用于输入所需属性值的界面。还必须输入任何二级索引。
如果您需要更多属性,请选择消息左侧的操作菜单。然后选择追加,以及所需的数据类型。
输入所有基本信息后,选择“保存”以添加项目。
如何在项目创建中使用Java?
在项目创建操作中使用 Java 包括创建 DynamoDB 类实例、Table 类实例、Item 类实例,以及指定要创建的项目的主键和属性。然后使用 putItem 方法添加新项目。
例子
DynamoDB dynamoDB = new DynamoDB (new AmazonDynamoDBClient( new ProfileCredentialsProvider())); Table table = dynamoDB.getTable("ProductList"); // Spawn a related items list List<Number> RELItems = new ArrayList<Number>(); RELItems.add(123); RELItems.add(456); RELItems.add(789); //Spawn a product picture map Map<String, String> photos = new HashMap<String, String>(); photos.put("Anterior", "http://xyz.com/products/101_front.jpg"); photos.put("Posterior", "http://xyz.com/products/101_back.jpg"); photos.put("Lateral", "http://xyz.com/products/101_LFTside.jpg"); //Spawn a product review map Map<String, List<String>> prodReviews = new HashMap<String, List<String>>(); List<String> fiveStarRVW = new ArrayList<String>(); fiveStarRVW.add("Shocking high performance."); fiveStarRVW.add("Unparalleled in its market."); prodReviews.put("5 Star", fiveStarRVW); List<String> oneStarRVW = new ArrayList<String>(); oneStarRVW.add("The worst offering in its market."); prodReviews.put("1 Star", oneStarRVW); // Generate the item Item item = new Item() .withPrimaryKey("Id", 101) .withString("Nomenclature", "PolyBlaster 101") .withString("Description", "101 description") .withString("Category", "Hybrid Power Polymer Cutter") .withString("Make", "Brand – XYZ") .withNumber("Price", 50000) .withString("ProductCategory", "Laser Cutter") .withBoolean("Availability", true) .withNull("Qty") .withList("ItemsRelated", RELItems) .withMap("Images", photos) .withMap("Reviews", prodReviews); // Add item to the table PutItemOutcome outcome = table.putItem(item);
您还可以查看以下更大的示例。
注意- 以下示例可能假设先前创建的数据源。在尝试执行之前,获取支持库并创建必要的数据源(具有所需特征的表或其他引用源)。
以下示例还使用 Eclipse IDE、AWS 凭证文件以及 Eclipse AWS Java 项目中的 AWS Toolkit。
package com.amazonaws.codesamples.document; import java.io.IOException; import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import com.amazonaws.auth.profile.ProfileCredentialsProvider; import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient; import com.amazonaws.services.dynamodbv2.document.DeleteItemOutcome; import com.amazonaws.services.dynamodbv2.document.DynamoDB; import com.amazonaws.services.dynamodbv2.document.Item; import com.amazonaws.services.dynamodbv2.document.Table; import com.amazonaws.services.dynamodbv2.document.UpdateItemOutcome; import com.amazonaws.services.dynamodbv2.document.spec.DeleteItemSpec; import com.amazonaws.services.dynamodbv2.document.spec.UpdateItemSpec; import com.amazonaws.services.dynamodbv2.document.utils.NameMap; import com.amazonaws.services.dynamodbv2.document.utils.ValueMap; import com.amazonaws.services.dynamodbv2.model.ReturnValue; public class CreateItemOpSample { static DynamoDB dynamoDB = new DynamoDB(new AmazonDynamoDBClient ( new ProfileCredentialsProvider())); static String tblName = "ProductList"; public static void main(String[] args) throws IOException { createItems(); retrieveItem(); // Execute updates updateMultipleAttributes(); updateAddNewAttribute(); updateExistingAttributeConditionally(); // Item deletion deleteItem(); } private static void createItems() { Table table = dynamoDB.getTable(tblName); try { Item item = new Item() .withPrimaryKey("ID", 303) .withString("Nomenclature", "Polymer Blaster 4000") .withStringSet( "Manufacturers", new HashSet<String>(Arrays.asList("XYZ Inc.", "LMNOP Inc."))) .withNumber("Price", 50000) .withBoolean("InProduction", true) .withString("Category", "Laser Cutter"); table.putItem(item); item = new Item() .withPrimaryKey("ID", 313) .withString("Nomenclature", "Agitatatron 2000") .withStringSet( "Manufacturers", new HashSet<String>(Arrays.asList("XYZ Inc,", "CDE Inc."))) .withNumber("Price", 40000) .withBoolean("InProduction", true) .withString("Category", "Agitator"); table.putItem(item); } catch (Exception e) { System.err.println("Cannot create items."); System.err.println(e.getMessage()); } } }
DynamoDB - 获取项目
在 DynamoDB 中检索项目需要使用 GetItem,并指定表名称和项目主键。请务必包含完整的主键,而不是省略一部分。
例如,省略组合键的排序键。
GetItem Behave符合三个默认值 -
- 它作为最终一致读取执行。
- 它提供了所有属性。
- 它没有详细说明其容量单位消耗。
这些参数允许您覆盖默认的 GetItem Behave。
取回物品
DynamoDB 通过跨多个服务器维护项目的多个副本来确保可靠性。每次成功的写入都会创建这些副本,但需要大量时间来执行;意思最终一致。这意味着您无法在写入项目后立即尝试读取。
您可以更改 GetItem 的默认最终一致性读取,但是,更多当前数据的成本仍然是消耗更多容量单位;具体来说,是两倍。注意 DynamoDB 通常会在一秒钟内实现每个副本的一致性。
您可以使用 GUI 控制台、Java 或其他工具来执行此任务。
使用 Java 进行项目检索
在项目检索操作中使用 Java 需要创建 DynamoDB 类实例、表类实例,并调用表实例的 getItem 方法。然后指定该项目的主键。
您可以查看以下示例 -
DynamoDB dynamoDB = new DynamoDB(new AmazonDynamoDBClient( new ProfileCredentialsProvider())); Table table = dynamoDB.getTable("ProductList"); Item item = table.getItem("IDnum", 109);
在某些情况下,您需要指定此操作的参数。
以下示例使用.withProjectionExpression和GetItemSpec作为检索规范 -
GetItemSpec spec = new GetItemSpec() .withPrimaryKey("IDnum", 122) .withProjectionExpression("IDnum, EmployeeName, Department") .withConsistentRead(true); Item item = table.getItem(spec); System.out.println(item.toJSONPretty());
您还可以查看以下更大的示例以更好地理解。
注意- 以下示例可能假设先前创建的数据源。在尝试执行之前,获取支持库并创建必要的数据源(具有所需特征的表或其他引用源)。
此示例还使用 Eclipse IDE、AWS 凭证文件以及 Eclipse AWS Java 项目中的 AWS Toolkit。
package com.amazonaws.codesamples.document; import java.io.IOException import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import com.amazonaws.auth.profile.ProfileCredentialsProvider; import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient; import com.amazonaws.services.dynamodbv2.document.DeleteItemOutcome; import com.amazonaws.services.dynamodbv2.document.DynamoDB; import com.amazonaws.services.dynamodbv2.document.Item; import com.amazonaws.services.dynamodbv2.document.Table; import com.amazonaws.services.dynamodbv2.document.UpdateItemOutcome; import com.amazonaws.services.dynamodbv2.document.spec.DeleteItemSpec; import com.amazonaws.services.dynamodbv2.document.spec.UpdateItemSpec; import com.amazonaws.services.dynamodbv2.document.utils.NameMap; import com.amazonaws.services.dynamodbv2.document.utils.ValueMap; import com.amazonaws.services.dynamodbv2.model.ReturnValue; public class GetItemOpSample { static DynamoDB dynamoDB = new DynamoDB(new AmazonDynamoDBClient( new ProfileCredentialsProvider())); static String tblName = "ProductList"; public static void main(String[] args) throws IOException { createItems(); retrieveItem(); // Execute updates updateMultipleAttributes(); updateAddNewAttribute(); updateExistingAttributeConditionally(); // Item deletion deleteItem(); } private static void createItems() { Table table = dynamoDB.getTable(tblName); try { Item item = new Item() .withPrimaryKey("ID", 303) .withString("Nomenclature", "Polymer Blaster 4000") .withStringSet( "Manufacturers", new HashSet<String>(Arrays.asList("XYZ Inc.", "LMNOP Inc."))) .withNumber("Price", 50000) .withBoolean("InProduction", true) .withString("Category", "Laser Cutter"); table.putItem(item); item = new Item() .withPrimaryKey("ID", 313) .withString("Nomenclature", "Agitatatron 2000") .withStringSet( "Manufacturers", new HashSet<String>(Arrays.asList("XYZ Inc,", "CDE Inc."))) .withNumber("Price", 40000) .withBoolean("InProduction", true) .withString("Category", "Agitator"); table.putItem(item); } catch (Exception e) { System.err.println("Cannot create items."); System.err.println(e.getMessage()); } } private static void retrieveItem() { Table table = dynamoDB.getTable(tableName); try { Item item = table.getItem("ID", 303, "ID, Nomenclature, Manufacturers", null); System.out.println("Displaying retrieved items..."); System.out.println(item.toJSONPretty()); } catch (Exception e) { System.err.println("Cannot retrieve items."); System.err.println(e.getMessage()); } } }
DynamoDB - 更新项目
更新 DynamoDB 中的项目主要包括指定项目的完整主键和表名称。它需要为您修改的每个属性提供一个新值。该操作使用UpdateItem,它修改现有项目或在发现丢失项目时创建它们。
在更新中,您可能希望通过显示操作之前和之后的原始值和新值来跟踪更改。UpdateItem 使用ReturnValues参数来实现此目的。
注意- 该操作不报告容量单位消耗,但您可以使用ReturnConsumedCapacity参数。
使用 GUI 控制台、Java 或任何其他工具来执行此任务。
如何使用 GUI 工具更新项目?
导航到控制台。在左侧导航窗格中,选择“表格”。选择所需的表,然后选择“项目”选项卡。
选择需要更新的项目,然后选择操作 | 编辑。
在“编辑项目”窗口中修改任何必要的属性或值。
使用 Java 更新项目
使用Java进行项目更新操作需要创建一个Table类实例,并调用其updateItem方法。然后指定项目的主键,并提供详细说明属性修改的UpdateExpression。
以下是相同的示例 -
DynamoDB dynamoDB = new DynamoDB(new AmazonDynamoDBClient( new ProfileCredentialsProvider())); Table table = dynamoDB.getTable("ProductList"); Map<String, String> expressionAttributeNames = new HashMap<String, String>(); expressionAttributeNames.put("#M", "Make"); expressionAttributeNames.put("#P", "Price expressionAttributeNames.put("#N", "ID"); Map<String, Object> expressionAttributeValues = new HashMap<String, Object>(); expressionAttributeValues.put(":val1", new HashSet<String>(Arrays.asList("Make1","Make2"))); expressionAttributeValues.put(":val2", 1); //Price UpdateItemOutcome outcome = table.updateItem( "internalID", // key attribute name 111, // key attribute value "add #M :val1 set #P = #P - :val2 remove #N", // UpdateExpression expressionAttributeNames, expressionAttributeValues);
updateItem方法还允许指定条件,可以在以下示例中看到-
Table table = dynamoDB.getTable("ProductList"); Map<String, String> expressionAttributeNames = new HashMap<String, String>(); expressionAttributeNames.put("#P", "Price"); Map<String, Object> expressionAttributeValues = new HashMap<String, Object>(); expressionAttributeValues.put(":val1", 44); // change Price to 44 expressionAttributeValues.put(":val2", 15); // only if currently 15 UpdateItemOutcome outcome = table.updateItem (new PrimaryKey("internalID",111), "set #P = :val1", // Update "#P = :val2", // Condition expressionAttributeNames, expressionAttributeValues);
使用计数器更新项目
DynamoDB 允许Atomics计数器,这意味着使用 UpdateItem 递增/递减属性值而不影响其他请求;此外,计数器始终更新。
以下是解释如何完成此操作的示例。
注意- 以下示例可能假设先前创建的数据源。在尝试执行之前,获取支持库并创建必要的数据源(具有所需特征的表或其他引用源)。
此示例还使用 Eclipse IDE、AWS 凭证文件以及 Eclipse AWS Java 项目中的 AWS Toolkit。
package com.amazonaws.codesamples.document; import java.io.IOException; import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import com.amazonaws.auth.profile.ProfileCredentialsProvider; import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient; import com.amazonaws.services.dynamodbv2.document.DeleteItemOutcome; import com.amazonaws.services.dynamodbv2.document.DynamoDB; import com.amazonaws.services.dynamodbv2.document.Item; import com.amazonaws.services.dynamodbv2.document.Table; import com.amazonaws.services.dynamodbv2.document.UpdateItemOutcome; import com.amazonaws.services.dynamodbv2.document.spec.DeleteItemSpec; import com.amazonaws.services.dynamodbv2.document.spec.UpdateItemSpec; import com.amazonaws.services.dynamodbv2.document.utils.NameMap; import com.amazonaws.services.dynamodbv2.document.utils.ValueMap; import com.amazonaws.services.dynamodbv2.model.ReturnValue; public class UpdateItemOpSample { static DynamoDB dynamoDB = new DynamoDB(new AmazonDynamoDBClient( new ProfileCredentialsProvider())); static String tblName = "ProductList"; public static void main(String[] args) throws IOException { createItems(); retrieveItem(); // Execute updates updateMultipleAttributes(); updateAddNewAttribute(); updateExistingAttributeConditionally(); // Item deletion deleteItem(); } private static void createItems() { Table table = dynamoDB.getTable(tblName); try { Item item = new Item() .withPrimaryKey("ID", 303) .withString("Nomenclature", "Polymer Blaster 4000") .withStringSet( "Manufacturers", new HashSet<String>(Arrays.asList("XYZ Inc.", "LMNOP Inc."))) .withNumber("Price", 50000) .withBoolean("InProduction", true) .withString("Category", "Laser Cutter"); table.putItem(item); item = new Item() .withPrimaryKey("ID", 313) .withString("Nomenclature", "Agitatatron 2000") .withStringSet( "Manufacturers", new HashSet<String>(Arrays.asList("XYZ Inc,", "CDE Inc."))) .withNumber("Price", 40000) .withBoolean("InProduction", true) .withString("Category", "Agitator"); table.putItem(item); } catch (Exception e) { System.err.println("Cannot create items."); System.err.println(e.getMessage()); } } private static void updateAddNewAttribute() { Table table = dynamoDB.getTable(tableName); try { Map<String, String> expressionAttributeNames = new HashMap<String, String>(); expressionAttributeNames.put("#na", "NewAttribute"); UpdateItemSpec updateItemSpec = new UpdateItemSpec() .withPrimaryKey("ID", 303) .withUpdateExpression("set #na = :val1") .withNameMap(new NameMap() .with("#na", "NewAttribute")) .withValueMap(new ValueMap() .withString(":val1", "A value")) .withReturnValues(ReturnValue.ALL_NEW); UpdateItemOutcome outcome = table.updateItem(updateItemSpec); // Confirm System.out.println("Displaying updated item..."); System.out.println(outcome.getItem().toJSONPretty()); } catch (Exception e) { System.err.println("Cannot add an attribute in " + tableName); System.err.println(e.getMessage()); } } }
DynamoDB - 删除项目
删除 DynamoDB 中的项目仅需要提供表名称和项目键。还强烈建议使用条件表达式,这对于避免删除错误的项目是必要的。
与往常一样,您可以使用 GUI 控制台、Java 或任何其他所需的工具来执行此任务。
使用 GUI 控制台删除项目
导航到控制台。在左侧导航窗格中,选择“表格”。然后选择表名称和“项目”选项卡。
选择要删除的项目,然后选择操作| 删除。
然后将出现“删除项目”对话框,如以下屏幕截图所示。选择“删除”进行确认。
如何使用Java删除项目?
在项目删除操作中使用 Java 仅涉及创建 DynamoDB 客户端实例,并通过使用项目的键调用deleteItem方法。
您可以看到下面的示例,其中已对其进行了详细解释。
DynamoDB dynamoDB = new DynamoDB(new AmazonDynamoDBClient( new ProfileCredentialsProvider())); Table table = dynamoDB.getTable("ProductList"); DeleteItemOutcome outcome = table.deleteItem("IDnum", 151);
您还可以指定参数以防止错误删除。只需使用ConditionExpression即可。
例如 -
Map<String,Object> expressionAttributeValues = new HashMap<String,Object>(); expressionAttributeValues.put(":val", false); DeleteItemOutcome outcome = table.deleteItem("IDnum",151, "Ship = :val", null, // doesn't use ExpressionAttributeNames expressionAttributeValues);
下面是一个更大的例子,以便更好地理解。
注意- 以下示例可能假设先前创建的数据源。在尝试执行之前,获取支持库并创建必要的数据源(具有所需特征的表或其他引用源)。
此示例还使用 Eclipse IDE、AWS 凭证文件以及 Eclipse AWS Java 项目中的 AWS Toolkit。
package com.amazonaws.codesamples.document; import java.io.IOException; import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import com.amazonaws.auth.profile.ProfileCredentialsProvider; import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient; import com.amazonaws.services.dynamodbv2.document.DeleteItemOutcome; import com.amazonaws.services.dynamodbv2.document.DynamoDB; import com.amazonaws.services.dynamodbv2.document.Item; import com.amazonaws.services.dynamodbv2.document.Table; import com.amazonaws.services.dynamodbv2.document.UpdateItemOutcome; import com.amazonaws.services.dynamodbv2.document.spec.DeleteItemSpec; import com.amazonaws.services.dynamodbv2.document.spec.UpdateItemSpec; import com.amazonaws.services.dynamodbv2.document.utils.NameMap; import com.amazonaws.services.dynamodbv2.document.utils.ValueMap; import com.amazonaws.services.dynamodbv2.model.ReturnValue; public class DeleteItemOpSample { static DynamoDB dynamoDB = new DynamoDB(new AmazonDynamoDBClient( new ProfileCredentialsProvider())); static String tblName = "ProductList"; public static void main(String[] args) throws IOException { createItems(); retrieveItem(); // Execute updates updateMultipleAttributes(); updateAddNewAttribute(); updateExistingAttributeConditionally(); // Item deletion deleteItem(); } private static void createItems() { Table table = dynamoDB.getTable(tblName); try { Item item = new Item() .withPrimaryKey("ID", 303) .withString("Nomenclature", "Polymer Blaster 4000") .withStringSet( "Manufacturers", new HashSet<String>(Arrays.asList("XYZ Inc.", "LMNOP Inc."))) .withNumber("Price", 50000) .withBoolean("InProduction", true) .withString("Category", "Laser Cutter"); table.putItem(item); item = new Item() .withPrimaryKey("ID", 313) .withString("Nomenclature", "Agitatatron 2000") .withStringSet( "Manufacturers", new HashSet<String>(Arrays.asList("XYZ Inc,", "CDE Inc."))) .withNumber("Price", 40000) .withBoolean("InProduction", true) .withString("Category", "Agitator"); table.putItem(item); } catch (Exception e) { System.err.println("Cannot create items."); System.err.println(e.getMessage());