はじめに

データを保存するための多くのオプションの中で、クラウド内の情報ストレージを研究するための新しい興味深い技術を間違いなく強調することができます。 現時点では、この種のサービスを提供するためのいくつかのサービスがあり、それらは指で数えることができます-これらは、Amazon Webサービス、Sun Cloud、Windows Azureです。 これらの各サービスは、データにアクセスするための独自のインターフェイスを提供します。この記事では、Windows Azureサービスについて詳しく説明します。
このクラウドコンピューティングプラットフォームは、3種類の情報ストレージサービスを提供します。
- Blobサービス。テキストとバイナリ情報を特別に編成されたBlobコンテナに保存できます。
- キューは、メッセージの無制限のストレージを整理できるサービスです(ドキュメントによると、各メッセージは8 kbを超えることはできません)。
- テーブルサービスでは、テーブルに構造化されたデータを保存でき、REST APIを介してアクセスできます。
上記の最後のサービスであるテーブルストレージは、一見するとリレーショナルテーブルストレージの類似物と見なすことができますが、記事の過程でその概念にいくつかの重要な違いがあることを明らかにします。
このストレージにはテーブル(テーブル)を含めることができます。テーブルストレージコンセプトのテーブルはエンティティ(エンティティ)のコレクションであり、リレーショナルストレージのタプルに似ています。エンティティは特定のプロパティ(プロパティ)のセットであり、名前と型付きの値のペア、エンティティはリレーショナルリポジトリのテーブルのフィールドに似ています。 ここで、テーブルストレージのテーブルは格納されたエンティティの構造を指定していないことに注意してください。むしろ、格納されたエンティティはさまざまなプロパティを含むことができますが、同じテーブルにあります。
- テーブル名を生成するためのルールを詳細に検討してください。
- テーブル名には英数字のみを含めることができます。
- テーブル名を数字で始めることはできません。
- テーブル名では大文字と小文字が区別されます。
- テーブル名は3〜63文字でなければなりません。
ここで、プロパティとエンティティの形成におけるいくつかの側面を検討します。
- プロパティ名は大文字と小文字が区別され、255文字を超えることはできません。
- 各エンティティには、最大253個のユーザー定義プロパティが必要です。
- 各エンティティの合計データサイズは1 mb以下である必要があります。
- 各エンティティには、以下で説明する3つのシステムプロパティが含まれている必要があります。
エンティティのシステムプロパティ。
バランスの取れたデータの読み込みをサポートするには、ストレージ内のテーブルをパーティション分割(パーティション)できるため、どのエンティティがどのパーティションに属しているかを明確に示すために、このエンティティが配置されているテーブルのパーティションを一意に識別するPartitionKeyプロパティを含める必要があります。
格納された各エンティティの別の必須プロパティは、特定のセクションの特定のエンティティを既に識別するRowKeyプロパティです。 説明されているRowKeyおよびPartitionKeyプロパティは、各エンティティのプライマリキーペアを形成し、挿入、削除、および更新操作中に指定する必要があります。
開発者にとって最も重要でない最後のプロパティはプロパティです。タイムスタンプは、サービスの内部ニーズを対象としており、エンティティの最終変更時刻に関する情報を保存します。
上記のように、テーブルストレージのデータにアクセスするためのREST APIがありますが、MicrosoftはADO.NET Data Servicesと呼ばれるデータにアクセスするための特別なライブラリを提供します(フレームワーク4.0の最新バージョンでは、WCF Data Servicesに名前が変更されました)。 このライブラリは、データスキーム、エンティティ、およびそれらのプロパティを操作するためのクラスを開発者に提供します。 Windows Azureデータサービス用のクライアントを作成する例を使用して、その使用方法を以下に示します。
テストデータモデルの作成
最初の技術データを準備したら、Azure Table Serviceのデモデータモデルの作成に進むことができます。 しかし、最初に、クライアントアプリケーションをテストおよび作成するための環境を準備する必要があります。 これを行うには、Visual StudioおよびWindows Azure SDKのアドオンをダウンロードしてインストールする必要があります
。http :
//www.microsoft.com/downloads/details.aspx? FamilyID = 5664019e-6860-4c33-9843-4eb40b297ab6&displaylang
= enその後、プログラミングに直接進むことができます。 これを行うには、Visual Studio 2010でTableServiceExampleという単純なコンソールアプリケーションを作成します。

System.Data.Services.Client、Microsoft.WindowsAzure.StorageClientアセンブリへのリンクを追加します。

次に、実装予定の声を出す番です。つまり、2つのエンティティのストレージを作成する必要があります。
- 製品には、名前、ブランド、価格、製品カテゴリへのリンクのフィールドが含まれている必要があります。
- 製品カテゴリには、カテゴリ識別子、名前のフィールドが含まれている必要があります。
私はすぐに、現在の実装のテーブルサービスが他のオブジェクトへの参照をサポートしないことを予約したいと思います(DBMS言語では、外部キーを維持する手段はありません)。したがって、バインディングと整合性のロジック全体は最終アプリケーションにあります。
データをアプリケーションオブジェクトにマッピングするには、TableServiceEntityから継承した後、対応するクラスを作成する必要があります。 作成されたオブジェクトに関連するいくつかの側面を特定したいだけです。1)すべての製品エンティティは1つのセクション(PartitionKey)に「ProductPartition」という名前で保存され、「ProductKindPartition」セクションのエンティティを表示します。2)RowKey識別子は、作成時に指定されたGuidオブジェクト。
「製品」クラスのソースコード:
public class Product : TableServiceEntity
{
public const string PartitionName = "ProductPartition" ;
public Product()
{
}
private Product( string partitionKey, string rowKey)
: base (partitionKey, rowKey)
{
}
public static Product Create()
{
string rowKey = Guid .NewGuid().ToString();
return new Product(PartitionName, rowKey);
}
public string Name { get ; set ; }
public string Trademark { get ; set ; }
public int Kind { get ; set ; }
}
* This source code was highlighted with Source Code Highlighter .
「製品タイプ」クラスのソースコード:
public class ProductKind : TableServiceEntity
{
public const string PartitionName = "ProductKindPartition" ;
public ProductKind()
{
}
private ProductKind( string partitionKey, string rowKey)
: base (partitionKey, rowKey)
{
}
public static ProductKind Create()
{
string rowKey = Guid .NewGuid().ToString();
return new ProductKind(PartitionName, rowKey);
}
public int Id { get ; set ; }
public string Name { get ; set ; }
}
* This source code was highlighted with Source Code Highlighter .
上記のエンティティを保存するために必要なテーブルを作成するには、次の基準でデータコンテキストを決定する必要があります。
1)コンテキストクラスは、TableServiceContextから継承する必要があります
2)テーブルごとに、IQueryable型のプロパティを定義する必要があります。DataItemTypeは、テーブルに格納されるエンティティの型です。
データコンテキストのソースコードを見てください。
public class TestServiceDataContext : TableServiceContext
{
public TestServiceDataContext( string baseAddress, StorageCredentials credentials)
: base (baseAddress, credentials)
{
}
public const string ProductTableName = "Product" ;
public const string ProductKindTableName = "ProductKind" ;
public IQueryable<Product> Product
{
get { return CreateQuery<Product>( ProductTableName ); }
}
public IQueryable<ProductKind> ProductKind
{
get { return CreateQuery<ProductKind>( ProductKindTableName ); }
}
}
* This source code was highlighted with Source Code Highlighter .
データスキームをテーブルサービスに展開する前に、Windows Azureデータサービス認証の原則を理解する必要があります。
テーブルサービスへのアクセスの設定
Azureテーブルデータサービスへの各リクエストは認証される必要があります。実際には、これは各REST APIリクエストに特別に形成された署名が含まれることを意味します。 詳細については説明しませんが、SDKの対応するセクションを読むことが興味深い場合は、Azure StorageのADO .NETデータサービスがすべての大雑把な作業を行うため、認証データを正しく指定するだけで済みます。 このようなデータは、アカウント名(アカウント)とアクセスキー(共有キー)です。
作成しているプログラムに何かを追加する前に、コンピューターでローカルストレージエミュレーターを実行する必要があります。すぐに、Expressを含むすべてのエディションのSQL Serverがインストールされている必要があることを予約する必要があります。 このプログラムはWindows Azure SDKに含まれており、その名前はDevelopment Storageです。 最初の起動の前に、アプリケーションはデータベースを作成して開始します。データベースは後で情報を保存するために使用します。 すべてがうまくいくと、通知領域に開発ストレージアイコンが表示され、それをクリックすると、現在実行中のサービスとそのローカルアドレスを確認できます。

それらの認証は、既知の事前生成データに従って行われます。
- アカウント名:devstoreaccount1
- アカウントキー:Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq / K1SZFPTOtr / KBHBeksoGMGw ==
アプリケーションで使用するのはこの情報です。 まず、構成ファイルApp.configを追加し、次の行をappSettingsセクションに書き込みます。
< configuration >
< appSettings >
< add key ="AccountName" value ="devstoreaccount1" />
< add key ="AccountSharedKey" value ="Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==" />
< add key ="TableStorageEndpoint" value ="http://127.0.0.1:10002/devstoreaccount1" />
</ appSettings >
</ configuration >
* This source code was highlighted with Source Code Highlighter .
次に、コードを適切にフォーマットするために、TableStoreManagerクラスを作成し、次のフィールドを追加します。
- StorageCredentialsAccountAndKeyタイプの_credentials-共有キー(共有キー)の認証スキームを介した、テーブルストレージ(テーブルストレージ)へのアクセスに関するデータを表します
- タイプCloudTableClientの_tableStorage-クリックしてテーブルストレージにアクセスします。
- TestServiceDataContext型の_context-前のセクションで作成されたクラスで、すべてのテーブルの説明が含まれます。
次に、記述されたTableStoreManagerのタイプでは、これらすべてのフィールドを次の行で初期化する必要があります。
string accountKey = ConfigurationManager .AppSettings[ "AccountSharedKey" ];
string tableBaseUri = ConfigurationManager .AppSettings[ "TableStorageEndpoint" ];
string accountName = ConfigurationManager .AppSettings[ "AccountName" ];
_credentials = new StorageCredentialsAccountAndKey(accountName, accountKey);
_tableStorage = new CloudTableClient(tableBaseUri, _credentials);
_context = new TestServiceDataContext(tableBaseUri, _credentials);
* This source code was highlighted with Source Code Highlighter .
初期化されたすべてのアクセスコンポーネントが揃ったので、テーブルを作成する必要があるかどうかを確認する必要があります。リポジトリで作成する必要がある場合は、別のTryCreateSchemaメソッドでこれを行います。
var list = from table in _tableStorage.ListTables()
where table == TestServiceDataContext.ProductKindTableName
|| table == TestServiceDataContext.ProductTableName select table;
if (list != null && list.ToList< string >().Count == 0){
CloudTableClient.CreateTablesFromModel( typeof (TestServiceDataContext),
ConfigurationManager .AppSettings[ "TableStorageEndpoint" ],
_credentials);
}
* This source code was highlighted with Source Code Highlighter .
ここでは、まず、既存のテーブルのすべてのテーブルを選択し、それらの名前をスキーム内のテーブルと比較します。テーブルが見つからない場合、プログラムはTestServiceDataContextクラスで定義したモデルに従ってテーブルを作成します。 最後に、作成したメソッドの呼び出しを、以前に定義したInitializeメソッドに追加する必要があります。
ストレージからデータを取得しています。
Azure Table Storageには、ストレージ内のテーブルにクエリを作成するためのかなり多様なAPIがあります。たとえば、特定の数の要素を要求したり、最初の要素を返したり、特定のフィールドでフィルターしたりできます。 ただし、ここで問題のStorageの現在の実装にはいくつかの制限があります。まず、一度に1000を超える要素を返すことはできず、これらの少なくとも1つが5秒を超えて各要求を実行できないという事実条件が満たされない場合、サービスはエラーを返します。 しかし、クエリの作成に戻ると、ADO .NET Services Frameworkは、ウェアハウスサービスにREST APIを使用するルーチンを簡単にし、クエリをコンパイルするためのLINQ構文をユーザーに提供します。 残念ながら、データにアクセスするためのすべてのLINQ機能が現在の実装でサポートされているわけではありません。現在、使用できる演算子はわずかです。
- から-完全にサポート
- どこ-完全にサポート
- テイク-最大1000個の要素でサポート
- まず、FirstOrDefault-完全にサポートされています。
これでリストの終わりです。 クエリをコンパイルするには、TestServiceDataContext.CreateQueryメソッドを使用する必要があります。ここで、Tは返されたエンティティのタイプです。
利用可能なすべての製品を返すメソッドを作成します(1000要素の制限はまだ確認していません)
public List <Product> GetAllProducts()
{
var products = from product in _context.CreateQuery<Product>(TestServiceDataContext.ProductTableName) select product;
return products.ToList<Product>();
}
* This source code was highlighted with Source Code Highlighter .
次に、利用可能なすべてのカテゴリの選択と、その識別子による特定のカテゴリを作成します。
public List <ProductKind> GetProductKinds()
{
var productKinds = from productKind in
_context.CreateQuery<ProductKind>(TestServiceDataContext.ProductKindTableName)
select productKind;
return productKinds.ToList<ProductKind>();
}
public ProductKind GetProductKind( int id)
{
var productKinds = ( from productKind in
_context.CreateQuery<ProductKind>(TestServiceDataContext.ProductKindTableName)
where productKind.Id == id
select productKind);
var productKindList = productKinds.ToList<ProductKind>();
ProductKind result = null ;
if (productKindList.Count > 0) {
result = productKindList[0];
}
return result;
}
* This source code was highlighted with Source Code Highlighter .
今、私はサービスを仕事でチェックしたいと思いますが、それを開始してすべてが正しく機能する場合、リポジトリにデータがないため、何も表示されません。したがって、最初のデモでは、エンティティ追加メカニズムを実装する必要があります。
クラウドにデータを追加する
ADO .NETサービスを使用して新しいエンティティを追加する手順は非常に簡単に見えます。追加するエントリがテーブル全体で一意のRowKeyとPartiotionKeyを持っていることを確認してください。 挿入操作の場合、作成されたコンテキストTestServiceDataContext.AddObjectのメソッドに最初のパラメーター、追加が行われるテーブルの名前、および2番目のパラメーター、追加するオブジェクト自体を渡す必要があります。 その後、2つのメソッド(DataServiceContext.SaveChanges)を呼び出してクラウドストレージへの新しいデータの送信を強制し、DataServiceContext.Detach-コンテキストからオブジェクトへのリンクを削除します。 したがって、TableStoreManagerクラスでは、ProductエンティティとProductKindエンティティをそれぞれ追加する2つのInsertメソッドを作成します。
public void Insert(Product product)
{
_context.AddObject(TestServiceDataContext.ProductTableName, product);
_context.SaveChanges();
_context.Detach(product);
}
public void Insert(ProductKind productKind)
{
_context.AddObject(TestServiceDataContext.ProductKindTableName, productKind);
_context.SaveChanges();
_context.Detach(productKind);
}
* This source code was highlighted with Source Code Highlighter .
最初のサービステスト
Azure Table Storageのアーキテクチャに長い間触れた後、このサービスの動作を確認できます。このため、コンソールプログラムのMainメソッドに次の行を記述します。
try
{
TableStoreManager manager = new TableStoreManager();
manager.Initialize();
ProductKind productKind = ProductKind.Create();
productKind.Name = "" ;
productKind.Id = 1;
manager.Insert(productKind);
Product product = Product.Create();
product.Name = "" ;
product.Kind = productKind.Id;
product.Trademark = "Candy" ;
manager.Insert(product);
}
catch (Exception ex)
{
Console .WriteLine(ex.Message);
}
* This source code was highlighted with Source Code Highlighter .
このプログラムでは、まずテーブルサービス構造を初期化し、そこに必要なテーブルを作成し、次に、「Goods」テーブルと「Types of Goods」テーブルに1つのレコードを追加します。 ここで、テストする前に、ローカルの「クラウド」DevelopmentStorageを起動してプログラムを実行することを忘れないでください。 すべてが正しく書き込まれ、実行された場合、プログラムは数秒待機し、単一エラーなしで制御を返します。 次に、データが実際にローカルストレージに保存されていることを確認する必要があります。そのために、Mainメソッドを変更します。
try
{
TableStoreManager manager = new TableStoreManager();
manager.Initialize();
var products = manager.GetAllProducts();
foreach (Product product in products)
{
Console .WriteLine( ": {0} {1}" , product.Name, product.Trademark);
ProductKind productKind = manager.GetProductKind(product.Kind);
if (productKind != null )
{
Console .WriteLine( " : {0}" , productKind.Name);
}
}
}
catch (Exception ex)
{
Console .WriteLine(ex.Message);
}
* This source code was highlighted with Source Code Highlighter .
DevelopmentStorageを忘れずにプログラムをもう一度実行してみましょう。すべてが正しい場合、コンソールで保存されたすべてのデータが返され、処理の準備ができていることがわかります。

エンティティの更新
テーブルストレージ内のエンティティを更新するメカニズムは、変更するオブジェクトのRowKey値とPatitionKey値を指定する必要があるたびに非常に簡単です。 エンティティへの競争力のあるアクセスを確保するために、必須フラグEtag(REST APIのIf-Matchヘッダー)が導入されました。 このフラグは、このオブジェクトまたはそのオブジェクトがいつ変更されたかを決定し、このEtagが既存のストレージと一致しない場合、データの変更を許可せず、情報をリセットする必要があることを知らせるエラーを返します。 ただし、ETagで*記号を設定することにより、無条件の更新に独立して影響を与えることができます。
Ado .Net Data Servicesを介してオブジェクトを更新するには、最初にTableServiceContext.AttachToメソッドを使用してオブジェクトをコンテキストに追加し、次に同じオブジェクトをTableServiceContext.UpdateObjectメソッドに渡して呼び出し、TableServiceContext.SaveChangesメソッドを呼び出してサーバーに情報を送信する必要があります:
public void Update(Product product)
{
_context.Detach(product);
_context.AttachTo(TestServiceDataContext.ProductTableName, product, "*" );
_context.UpdateObject(product);
_context.SaveChanges();
}
* This source code was highlighted with Source Code Highlighter .
最初に、更新する前に、更新されたオブジェクトがAdo .NETサービスの視覚フィールドにないことを確認する必要があります。そのために、TableServiceContext.Detachメソッドを呼び出します。
これで、小さなテストを作成して、すべてが機能することを確認できます。
TableStoreManager manager = new TableStoreManager();
manager.Initialize();
var products = manager.GetAllProducts();
foreach (Product product in products)
{
product.Name += " 2" ;
product.Trademark = "" ;
manager.Update(product);
}
products = manager.GetAllProducts();
foreach (Product product in products)
{
Console .WriteLine(product.Name);
* This source code was highlighted with Source Code Highlighter .
記述されたコードを実行すると、データが正常に変更され、作成されたプロシージャのテストが完了したと見なすことができます。
エンティティの削除。
更新と同様に、オブジェクトの削除には2つのプロパティが必要です。これらはRowKeyとPartitionKeyであり、Etagフラグの指定も含みます。その動作は前のセクションで説明したものと似ています。 実際、エンティティは削除されると「削除済み」としてマークされ、クライアントからアクセスできなくなり、定期的なガベージコレクションが発生すると物理的に削除されます。 ADO .NETサービスを使用して-Productエンティティを削除するコードを以下に示します。
public void Delete(Product product)
{
_context.Detach(product);
_context.AttachTo(TestServiceDataContext.ProductTableName, product, "*" );
_context.DeleteObject(product);
_context.SaveChanges();
}
* This source code was highlighted with Source Code Highlighter .
正しい操作をテストするために、Mainメソッドに次の行を記述できます。
TableStoreManager manager = new TableStoreManager();
manager.Initialize();
var products = manager.GetAllProducts();
foreach (Product product in products)
{
Console .WriteLine( ": {0} {1}" , product.Name, product.Trademark);
manager.Delete(product);
}
products = manager.GetAllProducts();
if (products.ToArray().Length == 0)
{
Console .WriteLine( " " );
}
* This source code was highlighted with Source Code Highlighter .
おわりに
この記事では、クラウドサービスのいずれかのタイプにアクセスするための一般的なアプローチを示しました。 Ado .NET Servicesライブラリには、別の記事を書くことができる興味深いニュアンスがたくさんあるので、追加の条件でコードに負担をかけないようにしましたが、できるだけ軽くしました。
残念ながら、現在ロシアの消費者は本格的なバージョンのAzureプラットフォームを利用できないため、記述された例をテストすることはできません。 ただし、著者は2009年の春からCTPへの招待の所有者であり、実際のクラウド上でAzureに精通するために一定量(制限付き)のサービスを作成する権利を与えています。 この点で、約1年前からノンストップで実行されているクラウドサービスを作成することで、このアプローチを1年前にテストしました(2009年6月に開始されました)。
PS
ソースは
ここからダウンロードでき
ます