使用亚马逊 DynamoDB 没有数据库 SQL - Amazon SDK for .NET
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅 中国的 Amazon Web Services 服务入门 (PDF)

本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。

使用亚马逊 DynamoDB 没有数据库 SQL

注意

这两个主题中的编程模型都包含在两个主题中。 NET框架和. NET(Core),但调用约定有所不同,无论是同步还是异步。

Amazon SDK for .NET 支持 Amazon DynamoDB,这是一项由提供的快速SQL无数据库服务。 Amazon SDK提供了三种用于与 DynamoDB 通信的编程模型:低级模型、文档模型和对象持久化模型。

以下信息介绍了这些模型及其模型APIs,提供了如何以及何时使用它们的示例,并提供了指向中其他 DynamoDB 编程资源的链接。 Amazon SDK for .NET

低级模型

低级编程模型封装对 DynamoDB 服务的直接调用。您可以通过 Amazon.D ynamoDBv 2 命名空间访问此模型。

在三种模型中,低级模型需要编写的代码最多。例如,您必须转换。 NET数据类型与 DynamoDB 中的等效数据类型相同。但是,此模型向您提供了对大部分功能的访问。

以下示例显示如何使用低级模型创建表、修改表以及将项目插入到 DynamoDB 中的表。

创建表

在以下示例中,您可以使用 CreateTable 类的 AmazonDynamoDBClient 方法创建表。CreateTable 方法使用包含特性的 CreateTableRequest 类的实例,例如必需的项目属性名称、主键定义和吞吐容量。该 CreateTable 方法返回 CreateTableResponse 类的实例。

// using Amazon.DynamoDBv2; // using Amazon.DynamoDBv2.Model; var client = new AmazonDynamoDBClient(); Console.WriteLine("Getting list of tables"); List<string> currentTables = client.ListTables().TableNames; Console.WriteLine("Number of tables: " + currentTables.Count); if (!currentTables.Contains("AnimalsInventory")) { var request = new CreateTableRequest { TableName = "AnimalsInventory", AttributeDefinitions = new List<AttributeDefinition> { new AttributeDefinition { AttributeName = "Id", // "S" = string, "N" = number, and so on. AttributeType = "N" }, new AttributeDefinition { AttributeName = "Type", AttributeType = "S" } }, KeySchema = new List<KeySchemaElement> { new KeySchemaElement { AttributeName = "Id", // "HASH" = hash key, "RANGE" = range key. KeyType = "HASH" }, new KeySchemaElement { AttributeName = "Type", KeyType = "RANGE" }, }, ProvisionedThroughput = new ProvisionedThroughput { ReadCapacityUnits = 10, WriteCapacityUnits = 5 }, }; var response = client.CreateTable(request); Console.WriteLine("Table created with request ID: " + response.ResponseMetadata.RequestId); }

验证该表已准备好修改

您必须先准备好表进行修改,然后才能更改或修改表。以下示例显示了如何使用低级模型验证 DynamoDB 中的表已准备就绪。在此示例中,通过 DescribeTable 类的 AmazonDynamoDBClient 方法引用要检查的目标表。该代码每五秒检查一次表的 TableStatus 属性的值。当状态设置为 ACTIVE 时,表已准备好供修改。

// using Amazon.DynamoDBv2; // using Amazon.DynamoDBv2.Model; var client = new AmazonDynamoDBClient(); var status = ""; do { // Wait 5 seconds before checking (again). System.Threading.Thread.Sleep(TimeSpan.FromSeconds(5)); try { var response = client.DescribeTable(new DescribeTableRequest { TableName = "AnimalsInventory" }); Console.WriteLine("Table = {0}, Status = {1}", response.Table.TableName, response.Table.TableStatus); status = response.Table.TableStatus; } catch (ResourceNotFoundException) { // DescribeTable is eventually consistent. So you might // get resource not found. } } while (status != TableStatus.ACTIVE);

将项目插入到表中

在以下示例中,您使用低级模型将两个项目插入到 DynamoDB 中的表。每个项目通过 PutItem 类的 AmazonDynamoDBClient 方法插入,使用 PutItemRequest 类的实例。PutItemRequest 类的两个实例中的每个实例都接受将要插入项目的表名以及一系列项目属性值。

// using Amazon.DynamoDBv2; // using Amazon.DynamoDBv2.Model; var client = new AmazonDynamoDBClient(); var request1 = new PutItemRequest { TableName = "AnimalsInventory", Item = new Dictionary<string, AttributeValue> { { "Id", new AttributeValue { N = "1" }}, { "Type", new AttributeValue { S = "Dog" }}, { "Name", new AttributeValue { S = "Fido" }} } }; var request2 = new PutItemRequest { TableName = "AnimalsInventory", Item = new Dictionary<string, AttributeValue> { { "Id", new AttributeValue { N = "2" }}, { "Type", new AttributeValue { S = "Cat" }}, { "Name", new AttributeValue { S = "Patches" }} } }; client.PutItem(request1); client.PutItem(request2);

文档模型

文档编程模型提供了一种更简单的方法来处理 DynamoDB 中的数据。此模型专门用于访问表和表中的项目。您可以通过 Amazon.D 访问此模型 ynamoDBv 2. DocumentModel命名空间。

与低级编程模型相比,使用文档模型更容易针对 DynamoDB 数据编写代码。例如,您不必转换那么多。 NET数据类型与 DynamoDB 中的等效数据类型相同。不过,使用此模型所能访问的功能没有低级编程模型所提供的多。例如,您可以使用此模型创建、检索、更新和删除表中的项目。但是,要创建表,您必须使用低级模型。与对象持久化模型相比,此模型需要您编写更多的代码来存储、加载和查询。 NET物体。

有关 DynamoDB 文档编程模型的更多信息,请参阅。 NET:亚马逊 DynamoDB 开发者指南中的文档模型。

以下各节提供有关如何创建所需的 DynamoDB 表的表示形式的信息,以及如何使用文档模型将项目插入表和从表中获取项目的示例。

创建表的表示形式

要使用文档模型执行数据操作,您必须首先创建 Table 类的实例,它会代表特定的表。有两种主要方式可执行此操作:

LoadTable 方法

第一种机制是使用 Table 类的静态 LoadTable 方法之一,类似于以下示例:

var client = new AmazonDynamoDBClient(); Table table = Table.LoadTable(client, "Reply");
注意

虽然这种机制起作用,但在某些条件下,由于冷启动和线程池行为,它有时会导致额外的延迟或死锁。有关这些行为的更多信息,请参阅博客文章 Improved DynamoDB Initialization Patterns for the Amazon SDK for .NET

TableBuilder

D AWSSDK. ynamoDBv 2 NuGet 软件包的 3.7.203 版本中引入了另一种机制,即TableBuilder类。该机制可以通过删除某些隐式方法调用(特别是 DescribeTable 方法)来解决上述行为。此机制的使用方式类似于以下示例:

var client = new AmazonDynamoDBClient(); var table = new TableBuilder(client, "Reply") .AddHashKey("Id", DynamoDBEntryType.String) .AddRangeKey("ReplyDateTime", DynamoDBEntryType.String) .AddGlobalSecondaryIndex("PostedBy-Message-index", "Author", DynamoDBEntryType.String, "Message", DynamoDBEntryType.String) .Build();

有关此替代机制的更多信息,请再次参阅博客文章 Improved DynamoDB Initialization Patterns for the Amazon SDK for .NET

将项目插入到表中

在以下示例中,回复通过 Table 类的 PutItemAsync 方法插入到 Reply 表中。PutItemAsync 方法获取 Document 类的实例;Document 类只是已初始化属性的集合。

using Amazon.DynamoDBv2; using Amazon.DynamoDBv2.DocumentModel; // Create a representation of the "Reply" table // by using one of the mechanisms described previously. // Then, add a reply to the table. var newReply = new Document(); newReply["Id"] = Guid.NewGuid().ToString(); newReply["ReplyDateTime"] = DateTime.UtcNow; newReply["PostedBy"] = "Author1"; newReply["Message"] = "Thank you!"; await table.PutItemAsync(newReply);

从表中获取项目

在以下示例中,通过 Table 类的 GetItemAsync 方法检索回复。为了确定要获得的回复,该GetItemAsync方法使用目标回复 hash-and-range的主键。

using Amazon.DynamoDBv2; using Amazon.DynamoDBv2.DocumentModel; // Create a representation of the "Reply" table // by using one of the mechanisms described previously. // Then, get a reply from the table // where "guid" is the hash key and "datetime" is the range key. var reply = await table.GetItemAsync(guid, datetime); Console.WriteLine("Id = " + reply["Id"]); Console.WriteLine("ReplyDateTime = " + reply["ReplyDateTime"]); Console.WriteLine("PostedBy = " + reply["PostedBy"]); Console.WriteLine("Message = " + reply["Message"]);

前面的示例为 WriteLine 方法隐式将表值转换为字符串。您可以使用 DynamoDBEntry 类的多种“As[type]”方法执行显式转换。例如,您可以GUID通过以下AsGuid()方法将值IdPrimitive数据类型显式转换为数据类型:

var guid = reply["Id"].AsGuid();

对象持久化模型

对象持久化编程模型专为存储、加载和查询而设计。 NETDynamoDB 中的对象。您可以通过 Amazon.D 访问此模型 ynamoDBv 2. DataModel命名空间。

在三种模型中,使用对象持久性模型最容易针对要存储、加载或查询的 DynamoDB 数据编写代码。例如,您可以直接使用 DynamoDB 数据类型。但是,此模型仅提供对存储、加载和查询操作的访问权限。 NETDynamoDB 中的对象。例如,您可以使用此模型创建、检索、更新和删除表中的项目。但是,您必须先使用低级模型创建表,然后使用此模型来映射您的表。 NET表中的类。

有关 DynamoDB 对象持久化编程模型的更多信息,请参阅。 NET:亚马逊 DynamoD B 开发者指南中的对象持久化模型。

以下示例向您展示了如何定义。 NET表示 DynamoDB 项目的类,请使用的实例。 NET类用于将项目插入到 DynamoDB 表中,并使用的实例。 NETclass 来从表格中获取物品。

定义一个. NET表示表中某项的类

在下面的类定义示例中,DynamoDBTable属性指定表名,而DynamoDBHashKeyDynamoDBRangeKey属性则对表 hash-and-range的主键进行建模。定义 DynamoDBGlobalSecondaryIndexHashKey 属性的目的是为了可以构造对特定作者回复的查询。

using Amazon.DynamoDBv2; using Amazon.DynamoDBv2.DataModel; [DynamoDBTable("Reply")] public class Reply { [DynamoDBHashKey] public string Id { get; set; } [DynamoDBRangeKey(StoreAsEpoch = false)] public DateTime ReplyDateTime { get; set; } [DynamoDBGlobalSecondaryIndexHashKey("PostedBy-Message-Index", AttributeName ="PostedBy")] public string Author { get; set; } [DynamoDBGlobalSecondaryIndexRangeKey("PostedBy-Message-Index")] public string Message { get; set; } }

为对象持久性模型创建上下文

要使用适用于 DynamoDB 的对象持久性编程模型,您需要创建一个上下文,它提供到 DynamoDB 的连接,让您能够访问表、执行各种操作,以及执行查询。

基本上下文

以下代码示例演示如何创建最基本的上下文 。

using Amazon.DynamoDBv2; using Amazon.DynamoDBv2.DataModel; var client = new AmazonDynamoDBClient(); var context = new DynamoDBContext(client);

与 DisableFetchingTableMetadata 属性的上下文

以下示例显示了如何额外设置 DynamoDBContextConfig 类的 DisableFetchingTableMetadata 属性以防止隐式调用 DescribeTable 方法。

using Amazon.DynamoDBv2; using Amazon.DynamoDBv2.DataModel; var client = new AmazonDynamoDBClient(); var context = new DynamoDBContext(client, new DynamoDBContextConfig { DisableFetchingTableMetadata = true });

如果将该 DisableFetchingTableMetadata 属性设置为 false(默认值),如第一个示例所示,则可以省略 Reply 类中描述表项键和索引结构的属性。相反,这些属性将通过对 DescribeTable 方法的隐式调用推断出来。如第二个示例所示,如果 DisableFetchingTableMetadata 设置为 true,则对象持久性模型的方法(例如 SaveAsyncQueryAsync)完全依赖于 Reply 类中定义的属性。在这种情况下,不会调用 DescribeTable 方法。

注意

在某些情况下,由于冷启动和线程池行为,对 DescribeTable 方法的调用有时会导致额外的延迟或死锁。因此,有时避免调用该方法是有利的。

有关这些行为的更多信息,请参阅博客文章 Improved DynamoDB Initialization Patterns for the Amazon SDK for .NET

使用的实例. NET用于将项目插入表格的类

在此示例中,通过DynamoDBContext类的SaveAsync方法插入项目,该方法采用的初始化实例。 NET代表项目的类。

using Amazon.DynamoDBv2; using Amazon.DynamoDBv2.DataModel; // Create an appropriate context for the object persistence programming model, // examples of which have been described earlier. // Create an object that represents the new item. var reply = new Reply() { Id = Guid.NewGuid().ToString(), ReplyDateTime = DateTime.UtcNow, Author = "Author1", Message = "Thank you!" }; // Insert the item into the table. await context.SaveAsync<Reply>(reply, new DynamoDBOperationConfig { IndexName = "PostedBy-Message-index" });

使用 a 的实例。 NET从表中获取物品的类

在此示例中,使用 DynamoDBContext 类的 QueryAsync 方法创建了一个查询,用于查找“Author1”的所有记录。然后,通过查询的 GetNextSetAsync 方法检索项目。

using Amazon.DynamoDBv2; using Amazon.DynamoDBv2.DataModel; // Create an appropriate context for the object persistence programming model, // examples of which have been described earlier. // Construct a query that finds all replies by a specific author. var query = context.QueryAsync<Reply>("Author1", new DynamoDBOperationConfig { IndexName = "PostedBy-Message-index" }); // Display the result. var set = await query.GetNextSetAsync(); foreach (var item in set) { Console.WriteLine("Id = " + item.Id); Console.WriteLine("ReplyDateTime = " + item.ReplyDateTime); Console.WriteLine("PostedBy = " + item.Author); Console.WriteLine("Message = " + item.Message); }

有关对象持久性模型的其它信息

上面显示的示例和解释有时包括名为 DisableFetchingTableMetadataDynamoDBContext 类的属性。此属性在 AWSSDK.D. ynamoDBv 2 NuGet 包的 3.7.203 版本中引入,允许您避免某些可能由于冷启动和线程池行为而导致额外延迟或死锁的情况。有关更多信息,请参阅博客文章 Improved DynamoDB Initialization Patterns for the Amazon SDK for .NET

以下是有关此属性的一些其它信息。

  • 如果您正在使用,则可以在您的app.configweb.config文件中全局设置此属性。 NET框架。

  • 可以使用 AWSConfigsDynamoDB 类全局设置此属性,如下面的示例所示。

    // Set the DisableFetchingTableMetadata property globally // before constructing any context objects. AWSConfigsDynamoDB.Context.DisableFetchingTableMetadata = true; var client = new AmazonDynamoDBClient(); var context = new DynamoDBContext(client);
  • 在某些情况下,您无法将 DynamoDB 属性添加到中。 NET类;例如,如果该类是在依赖项中定义的。在这种情况下,仍然可以利用 DisableFetchingTableMetadata 属性。为此,除了 DisableFetchingTableMetadata 属性之外,还要使用 TableBuilder 类。该TableBuilder类也在. AWSSDKD. ynamoDBv 2 NuGet 软件包的 3.7.203 版本中引入。

    // Set the DisableFetchingTableMetadata property globally // before constructing any context objects. AWSConfigsDynamoDB.Context.DisableFetchingTableMetadata = true; var client = new AmazonDynamoDBClient(); var context = new DynamoDBContext(client); var table = new TableBuilder(client, "Reply") .AddHashKey("Id", DynamoDBEntryType.String) .AddRangeKey("ReplyDateTime", DynamoDBEntryType.String) .AddGlobalSecondaryIndex("PostedBy-Message-index", "Author", DynamoDBEntryType.String, "Message", DynamoDBEntryType.String) .Build(); // This registers the "Reply" table we constructed via the builder. context.RegisterTableDefinition(table); // Now operations like this will work, // even if the Reply class was not annotated with this index. var query = context.QueryAsync<Reply>("Author1", new DynamoDBOperationConfig() { IndexName = "PostedBy-Message-index" });

更多信息

使用编程 DynamoDB 信息和示例** Amazon SDK for .NET

低级模型信息和示例

文档模型信息和示例

对象持久性模型信息和示例