Anteckning
Åtkomst till den här sidan kräver auktorisering. Du kan prova att logga in eller ändra kataloger.
Åtkomst till den här sidan kräver auktorisering. Du kan prova att ändra kataloger.
GÄLLER FÖR: NoSQL
Azure Cosmos DB är en skalbar, globalt distribuerad, fullständigt hanterad databas. Det ger garanterad åtkomst med låg latens till dina data.
Den här artikeln beskriver hur du migrerar ditt .NET-program från Amazon DynamoDB till Azure Cosmos DB med minimala kodändringar. Mer information om Azure Cosmos DB finns i översiktsartikeln.
Begreppsmässiga skillnader
I följande tabell visas viktiga begreppsmässiga skillnader mellan Azure Cosmos DB och DynamoDB:
DynamoDB | Azure Cosmos DB |
---|---|
Inte tillämpligt | Databas |
Tabell | Samling |
Artikel | Dokument |
Attribut | Fält |
Sekundärt index | Sekundärt index |
Primärnyckel > partitionsnyckel | Partitionsnyckel |
Primärnyckel > sorteringsnyckel | Krävs inte |
Stream | Ändringsflöde |
Skriv beräkningsenhet | Begärandeenhet (flexibel, kan användas för läsningar eller skrivningar) |
Läs beräkningsenhet | Begärandeenhet (flexibel, kan användas för läsningar eller skrivningar) |
Global tabell | Krävs inte. Du kan välja regionen direkt när du etablerar Azure Cosmos DB-kontot. (Du kan ändra regionen senare.) |
Strukturella skillnader
JSON-strukturen i Azure Cosmos DB är enklare än JSON-strukturen i DynamoDB. I följande exempel visas skillnaderna.
DynamoDB
Följande JSON-objekt representerar dataformatet i DynamoDB:
{
TableName: "Music",
KeySchema: [
{
AttributeName: "Artist",
KeyType: "HASH", //Partition key
},
{
AttributeName: "SongTitle",
KeyType: "RANGE" //Sort key
}
],
AttributeDefinitions: [
{
AttributeName: "Artist",
AttributeType: "S"
},
{
AttributeName: "SongTitle",
AttributeType: "S"
}
],
ProvisionedThroughput: {
ReadCapacityUnits: 1,
WriteCapacityUnits: 1
}
}
Azure Cosmos DB
Följande JSON-objekt representerar dataformatet i Azure Cosmos DB:
{
"Artist": "",
"SongTitle": "",
"AlbumTitle": "",
"Year": 9999,
"Price": 0.0,
"Genre": "",
"Tags": ""
}
Migrera din kod
Den här artikeln är begränsad till att migrera ett programs kod till Azure Cosmos DB, vilket är en viktig aspekt av databasmigreringen. För att hjälpa dig att förstå hur migreringsprocessen fungerar jämför följande avsnitt koden mellan Amazon DynamoDB och Azure Cosmos DB.
Om du vill ladda ned källkoden klonar du följande lagringsplats:
git clone https://github.com/Azure-Samples/DynamoDB-to-CosmosDB
Förutsättningar
- .NET Framework 4.7.2.
- Den senaste versionen av Visual Studio med Azure-utvecklingsarbetsbelastningen. Du kan komma igång med den kostnadsfria Visual Studio Community IDE. Aktivera Azure-utveckling-arbetsbelastningen under installationen av Visual Studio.
- Åtkomst till ett Azure Cosmos DB för NoSQL-konto.
- Lokal installation av Amazon DynamoDB.
- Java 8.
- Nedladdningsbar version av Amazon DynamoDB. Kör den på port 8000. (Du kan ändra och konfigurera koden.)
Konfigurera din kod
Lägg till följande NuGet-paket i projektet:
Install-Package Microsoft.Azure.Cosmos
Upprätta en anslutning
DynamoDB
I Amazon DynamoDB använder du följande kod för att ansluta:
AmazonDynamoDBConfig addbConfig = new AmazonDynamoDBConfig() ;
addbConfig.ServiceURL = "endpoint";
try { aws_dynamodbclient = new AmazonDynamoDBClient( addbConfig ); }
Azure Cosmos DB
Om du vill ansluta Azure Cosmos DB uppdaterar du koden till:
client_documentDB = new CosmosClient(
"<nosql-account-endpoint>",
tokenCredential
);
Optimera anslutningen i Azure Cosmos DB
Med Azure Cosmos DB kan du använda följande alternativ för att optimera anslutningen:
ConnectionMode
: Använd direktanslutningsläge för att ansluta till datanoderna i Azure Cosmos DB-tjänsten. Använd endast gatewayläge för att initiera och cachelagra de logiska adresserna och uppdatera vid uppdateringar. Mer information finns i Anslutningslägen för Azure Cosmos DB SQL SDK.ApplicationRegion
: Använd det här alternativet för att ange önskad geo-replikerad region för interaktion med Azure Cosmos DB. Mer information finns i Distribuera dina data globalt med Azure Cosmos DB.ConsistencyLevel
: Använd det här alternativet om du vill åsidosätta standardkonsekvensnivån. Mer information finns i Konsekvensnivåer i Azure Cosmos DB.BulkExecutionMode
: Använd det här alternativet för att köra massåtgärder genom att angeAllowBulkExecution
egenskapen tilltrue
. Mer information finns i Massimportera data till ett Azure Cosmos DB för NoSQL-konto med hjälp av .NET SDK.client_cosmosDB = new CosmosClient(" Your connection string ",new CosmosClientOptions() { ConnectionMode=ConnectionMode.Direct, ApplicationRegion=Regions.EastUS2, ConsistencyLevel=ConsistencyLevel.Session, AllowBulkExecution=true });
Skapa containern
DynamoDB
Om du vill lagra data i Amazon DynamoDB måste du skapa tabellen först. Definiera schemat, nyckeltypen och attributen enligt följande kod:
// movies_key_schema
public static List<KeySchemaElement> movies_key_schema
= new List<KeySchemaElement>
{
new KeySchemaElement
{
AttributeName = partition_key_name,
KeyType = "HASH"
},
new KeySchemaElement
{
AttributeName = sort_key_name,
KeyType = "RANGE"
}
};
// key names for the Movies table
public const string partition_key_name = "year";
public const string sort_key_name = "title";
public const int readUnits=1, writeUnits=1;
// movie_items_attributes
public static List<AttributeDefinition> movie_items_attributes
= new List<AttributeDefinition>
{
new AttributeDefinition
{
AttributeName = partition_key_name,
AttributeType = "N"
},
new AttributeDefinition
{
AttributeName = sort_key_name,
AttributeType = "S"
}
CreateTableRequest request;
CreateTableResponse response;
// Build the 'CreateTableRequest' structure for the new table
request = new CreateTableRequest
{
TableName = table_name,
AttributeDefinitions = table_attributes,
KeySchema = table_key_schema,
// Provisioned-throughput settings are always required,
// although the local test version of DynamoDB ignores them.
ProvisionedThroughput = new ProvisionedThroughput( readUnits, writeUnits );
};
Azure Cosmos DB
I Amazon DynamoDB måste du etablera läsberäkningsenheterna och beräkningsenheterna för skrivning. I Azure Cosmos DB anger du dataflödet som enheter för begäranden per sekund (RU/s). Du kan använda RU/s för alla åtgärder dynamiskt. Data ordnas som databas, container och sedan objekt. Du kan ange dataflödet på databasnivå, på samlingsnivå eller både och.
Så här skapar du en databas:
await client_cosmosDB.CreateDatabaseIfNotExistsAsync(movies_table_name);
Så här skapar du en container:
await cosmosDatabase.CreateContainerIfNotExistsAsync(new ContainerProperties() { PartitionKeyPath = "/" + partitionKey, Id = new_collection_name }, provisionedThroughput);
Läsa in data
DynamoDB
Följande kod visar hur du läser in data i Amazon DynamoDB. Koden moviesArray
visar JSON-dokument och sedan måste du iterera igenom och läsa in JSON-dokumenten i Amazon DynamoDB.
int n = moviesArray.Count;
for( int i = 0, j = 99; i < n; i++ )
{
try
{
string itemJson = moviesArray[i].ToString();
Document doc = Document.FromJson(itemJson);
Task putItem = moviesTable.PutItemAsync(doc);
if( i >= j )
{
j++;
Console.Write( "{0,5:#,##0}, ", j );
if( j % 1000 == 0 )
Console.Write( "\n " );
j += 99;
}
await putItem;
Azure Cosmos DB
I Azure Cosmos DB kan du strömma och skriva med hjälp av moviesContainer.CreateItemStreamAsync()
. I det här exemplet deserialiseras dock JSON till MovieModel
typen för att demonstrera funktionen för typgjutning. Koden är flertrådad och använder den distribuerade arkitekturen i Azure Cosmos DB för att påskynda inläsningen.
List<Task> concurrentTasks = new List<Task>();
for (int i = 0, j = 99; i < n; i++)
{
try
{
MovieModel doc= JsonConvert.DeserializeObject<MovieModel>(moviesArray[i].ToString());
doc.Id = Guid.NewGuid().ToString();
concurrentTasks.Add(moviesContainer.CreateItemAsync(doc,new PartitionKey(doc.Year)));
{
j++;
Console.Write("{0,5:#,##0}, ", j);
if (j % 1000 == 0)
Console.Write("\n ");
j += 99;
}
}
catch (Exception ex)
{
Console.WriteLine("\n ERROR: Could not write the movie record #{0:#,##0}, because:\n {1}",
i, ex.Message);
operationFailed = true;
break;
}
}
await Task.WhenAll(concurrentTasks);
Skapa ett dokument
DynamoDB
Att skriva ett nytt dokument i Amazon DynamoDB är inte typsäkert. I följande exempel används newItem
som dokumenttyp:
Task<Document> writeNew = moviesTable.PutItemAsync(newItem, token);
await writeNew;
Azure Cosmos DB
Azure Cosmos DB ger typsäkerhet via en datamodell. I det här exemplet används en datamodell med namnet MovieModel
:
public class MovieModel
{
[JsonProperty("id")]
public string Id { get; set; }
[JsonProperty("title")]
public string Title{ get; set; }
[JsonProperty("year")]
public int Year { get; set; }
public MovieModel(string title, int year)
{
this.Title = title;
this.Year = year;
}
public MovieModel()
{
}
[JsonProperty("info")]
public MovieInfo MovieInfo { get; set; }
internal string PrintInfo()
{
if(this.MovieInfo!=null)
return string.Format("\nMovie with title:{1}\n Year: {2}, Actors: {3}\n Directors:{4}\n Rating:{5}\n", this.Id, this.Title, this.Year, String.Join(",",this.MovieInfo.Actors), this.MovieInfo, this.MovieInfo.Rating);
else
return string.Format("\nMovie with title:{0}\n Year: {1}\n", this.Title, this.Year);
}
}
I Azure Cosmos DB, newItem
är MovieModel
:
MovieModel movieModel = new MovieModel()
{
Id = Guid.NewGuid().ToString(),
Title = "The Big New Movie",
Year = 2018,
MovieInfo = new MovieInfo() { Plot = "Nothing happens at all.", Rating = 0 }
};
var writeNew= moviesContainer.CreateItemAsync(movieModel, new Microsoft.Azure.Cosmos.PartitionKey(movieModel.Year));
await writeNew;
Läsa ett dokument
DynamoDB
Om du vill läsa i Amazon DynamoDB måste du definiera primitiver:
// Create primitives for the HASH and RANGE portions of the primary key
Primitive hash = new Primitive(year.ToString(), true);
Primitive range = new Primitive(title, false);
Task<Document> readMovie = moviesTable.GetItemAsync(hash, range, token);
movie_record = await readMovie;
Azure Cosmos DB
Med Azure Cosmos DB är frågan naturlig (LINQ):
IQueryable<MovieModel> movieQuery = moviesContainer.GetItemLinqQueryable<MovieModel>(true)
.Where(f => f.Year == year && f.Title == title);
// The query is executed synchronously here, but can also be executed asynchronously via the IDocumentQuery<T> interface
foreach (MovieModel movie in movieQuery)
{
movie_record_cosmosdb = movie;
}
Dokumentsamlingen i föregående exempel är typsäker och innehåller ett naturligt frågealternativ.
Uppdatera ett objekt
DynamoDB
Så här uppdaterar du ett objekt i Amazon DynamoDB:
updateResponse = await client.UpdateItemAsync( updateRequest );
Azure Cosmos DB
I Azure Cosmos DB behandlas en uppdatering som Upsert
en åtgärd (d.v.s. infoga dokumentet om det inte finns):
await moviesContainer.UpsertItemAsync<MovieModel>(updatedMovieModel);
Ta bort ett dokument
DynamoDB
Om du vill ta bort ett objekt i Amazon DynamoDB måste du återigen använda primitiver:
Primitive hash = new Primitive(year.ToString(), true);
Primitive range = new Primitive(title, false);
DeleteItemOperationConfig deleteConfig = new DeleteItemOperationConfig( );
deleteConfig.ConditionalExpression = condition;
deleteConfig.ReturnValues = ReturnValues.AllOldAttributes;
Task<Document> delItem = table.DeleteItemAsync( hash, range, deleteConfig );
deletedItem = await delItem;
Azure Cosmos DB
I Azure Cosmos DB kan du hämta dokumentet och ta bort det asynkront:
var result= ReadingMovieItem_async_List_CosmosDB("select * from c where c.info.rating>7 AND c.year=2018 AND c.title='The Big New Movie'");
while (result.HasMoreResults)
{
var resultModel = await result.ReadNextAsync();
foreach (var movie in resultModel.ToList<MovieModel>())
{
await moviesContainer.DeleteItemAsync<MovieModel>(movie.Id, new PartitionKey(movie.Year));
}
}
Fråga dokument
DynamoDB
I Amazon DynamoDB krävs API-funktioner för att köra frågor mot data:
QueryOperationConfig config = new QueryOperationConfig( );
config.Filter = new QueryFilter( );
config.Filter.AddCondition( "year", QueryOperator.Equal, new DynamoDBEntry[ ] { 1992 } );
config.Filter.AddCondition( "title", QueryOperator.Between, new DynamoDBEntry[ ] { "B", "Hzz" } );
config.AttributesToGet = new List<string> { "year", "title", "info" };
config.Select = SelectValues.SpecificAttributes;
search = moviesTable.Query( config );
Azure Cosmos DB
I Azure Cosmos DB kan du göra projektion och filtrera i en enkel SQL-fråga:
var result = moviesContainer.GetItemQueryIterator<MovieModel>(
"select c.Year, c.Title, c.info from c where Year=1998 AND (CONTAINS(Title,'B') OR CONTAINS(Title,'Hzz'))");
För intervallåtgärder (till exempel between
) måste du göra en genomsökning i Amazon DynamoDB:
ScanRequest sRequest = new ScanRequest
{
TableName = "Movies",
ExpressionAttributeNames = new Dictionary<string, string>
{
{ "#yr", "year" }
},
ExpressionAttributeValues = new Dictionary<string, AttributeValue>
{
{ ":y_a", new AttributeValue { N = "1960" } },
{ ":y_z", new AttributeValue { N = "1969" } },
},
FilterExpression = "#yr between :y_a and :y_z",
ProjectionExpression = "#yr, title, info.actors[0], info.directors, info.running_time_secs"
};
ClientScanning_async( sRequest ).Wait( );
I Azure Cosmos DB kan du använda en SQL-fråga och en enradsinstruktion.
var result = moviesContainer.GetItemQueryIterator<MovieModel>(
"select c.title, c.info.actors[0], c.info.directors,c.info.running_time_secs from c where BETWEEN year 1960 AND 1969");
Ta bort en container
DynamoDB
Om du vill ta bort tabellen i Amazon DynamoDB kan du ange:
client.DeleteTableAsync( tableName );
Azure Cosmos DB
Om du vill ta bort samlingen i Azure Cosmos DB kan du ange:
await moviesContainer.DeleteContainerAsync();
Ta sedan även bort databasen om det behövs:
await cosmosDatabase.DeleteAsync();
Sammanfattning
Som föregående exempel visar stöder Azure Cosmos DB naturliga frågor (SQL) och åtgärder är asynkrona. Du kan enkelt migrera din komplexa kod till Azure Cosmos DB. Koden blir enklare efter migreringen.
Relaterat innehåll
- Lär dig mer om prestandaoptimering.
- Lär dig hur du optimerar läsningar och skrivningar.
- Lär dig mer om övervakning i Azure Cosmos DB.