login register Sysop! about ME  
qrcode
    최초 작성일 :    2012년 07월 30일
  최종 수정일 :    2012년 07월 30일
  작성자 :    hanhead
  편집자 :    hanhead (정 재훈)
  읽음수 :    21,382

강좌 목록으로 돌아가기

필자의 잡담~

이번 컬럼은 정재훈(hanhead)님이 번역하셨으며, Windows Azure의 Table 저장소에 대해서 설명하고 있습니다. 컬럼의 원문은 http://www.windowsazure.com/en-us/develop/net/how-to-guides/table-services/ 입니다.

이 글은 Windows Azure 공식 컬럼인 http://www.windowsazure.com/en-us/develop/net/how-to-guides/table-services/의 글을 편역한 내용입니다. 마이크로소프트의 공식 번역 문서가 아니며 태오 사이트 MS 컬럼 번역팀에서 번역한 내용입니다. 그렇기에, 일부 오역이나 오타가 존재할 수 있는 점 미리 양해를 구합니다. 원문에 대한 모든 저작권은 마이크로소프트에 있으며, 컬럼 내용과 관련한 질의 문답 역시 원문 사이트에 문의하시는 것을 추천드립니다.

테이블(Table) 저장소 서비스 사용하기

이번 가이드에서는 Windows Azure의 테이블 서비스를 이용하는 것에 관해 살펴보도록 하겠습니다. 이번에 사용되는 예제는 .NET API를 이용하여 C#으로 작성되었으며 테이블을 추가, 삭제하고 테이블에 엔티티(Entity)를 입력하고 조회하는 내용을 다루고 있습니다. 보다 더 많은 내용을 원하시는 분들은 강좌의 마지막에 있는 "다음으로 볼 내용들"을 참고해주십시오.

목차

  • 테이블 서비스란?
  • 개념
  • Windows Azure 저장소 계정 만들기
  • Visual Studio에서 Windows Azure 프로젝트 만들기
  • 응용 프로그램에서 저장소 접근 설정하기
  • Windows Azure 저장소 연결 문자열 설정하기
  • How To: 테이블 생성하기
  • How To: 테이블에 엔티티 추가하기
  • How To: 여러 엔티티를 한번에 추가하기(배치 작업)
  • How To: 동일 파티션에 속한 모든 엔티티 가져오기
  • How To: 동일 파티션의 엔티티를 일부만 가져오기
  • How To: 단일 엔티티만 가져오기
  • How To: 엔티티 수정하기
  • How To: 엔티티의 특정 속성만 조회하기
  • How To: 엔티티가 없으면 추가하고 있으면 변경하기
  • How To: 엔티티 삭제하기
  • 다음으로 볼 내용들

테이블 서비스란

Windows Azure 테이블 저장소 서비스는 구조화된 대량의 데이터를 저장할 수 있습니다. 이 서비스는 Windows Azure 클라우드(Cloud) 내부나 외부에서 인증을 통하여 호출할 수 있는 NoSQL유형의 데이터 저장소 입니다. Windows Azure 테이블은 구조화되어 있긴 하지만 비-관계적인 데이터를 저장하는데 이상적입니다. 일반적으로 아래와 같은 경우에 사용됩니다.

  • 웹 응용 프로그램에서 사용될 수 있는 테라 바이트 급의 구조화된 데이터를 저장하기 위해서
  • 복합적인 조인, 외래키(Foreign Key), 저장 프로시저(Stored Procedure)가 필요없고 데이터로의 빠른 접근을 위한 비정규화된 데이터 집합(Datasets)을 저장하기 위해서
  • 클러스트(Clustered) 색인을 통한 빠른 데이터 조회를 위해서
  • WCF 데이터 서비스 라이브러리(Data Service Library)를 이용하면서 OData 프로토콜과 LINQ를 사용하여 데이터에 접근하기 위해서

테이블 서비스는 구조화되어 있지만, 비-관계적인 대용량의 데이터를 저장하고 조회하는 경우에 사용할 수 있으며, 테이블들은 필요에 따라 자동으로 크기가 증가합니다.

개념

테이블 서비스는 아래와 같이 구성되어 있습니다.


출처 : http://www.windowsazure.com/media/devcenter/dotnet/table1.png

  • URL 형식 : 아래와 같은 URL형식으로 테이블의 주소가 만들어지고 REST API등에서 이용됩니다.

    http://<저장소 계정명>.table.core.windows.net/<테이블명>

    Azure 테이블 서비스는 해당 주소로 OData 프로토콜을 사용하여 접근할 수도 있습니다. OData에 관한 자세한 정보는 OData.org(http://www.odata.org/)를 참조하십시오.

  • 저장소 계정 : 다양한 Windows Azure 저장소에 접근하려면 저장소 계정을 이용해야 합니다. 단, 단일 저장소 계정 안에 있는 블랍(BLOB), 테이블, 큐(Queue)의 총 크기는 모두 합해서 100 TB를 초과할 수 없습니다.
  • 테이블(Table) : 테이블은 엔티티의 집합입니다. 테이블에 들어갈 수 있는 엔티티의 스키마(Schema)는 고정되어 있지 않습니다. 다시 말해, 서로 다른 속성들을 가진 엔티티가 하나의 테이블(Table)안에 포함될 수 있다는 겁니다. 단일 계정에서는 저장소 계정의 제한인 100테라바이트(TB) 한도까지 얼마든지 많은 테이블을 만들 수 있습니다.
  • 엔티티(Entity) : 엔티티는 속성들의 집합입니다. 데이터베이스에서 말하는 행(Row)과 유사한 개념으로 보시면 됩니다. 하나의 엔티티는 1 MB까지 사용이 가능합니다.
  • 속성(Property): 속성은 이름과 값의 쌍으로 이루어집니다. 각각의 엔티티는 속성을 252개까지 포함할 수 있습니다. 그리고, 각각의 엔티티는 3개의 시스템 속성(Partition Key, Row Key, Timestamp)을 가집니다. 엔티티들이 같은 파티션 키(Partition Key)를 가지게 되면 조회, 추가, 수정에 있어 단일문맥 처리(atomic operation)가 이루어지므로 더욱 빠릅니다. 로우 키(Row Key)는 하나의 파티션(Partition) 안에서 유일한 값입니다. 그리고, 속성에 사용할 수 있는 .NET 데이터 형식은 byte[], bool, int, int32, int64, long, double, GUID, string이며, byte array, string의 경우는 64 KB 크기까지 사용 가능합니다.

Windows Azure 저장소 계정 만들기

저장소 서비스를 사용하기 위해서는 Windows Azure 저장소 계정이 필요합니다. 아래와 같은 순서대로 따라 하시면 수동으로 저장소 계정을 생성할 수 있습니다. (REST API를 이용하여 프로그램을 만들어서 저장소 계정을 생성할 수도 있습니다):

  1. Windows Azure 관리 포탈에 로그인합니다.
  2. 하단 메뉴 바의 좌측에 있는 +NEW 버튼을 클릭합니다.


    출처 : http://www.windowsazure.com/media/devcenter/shared/plus-new.png

  3. Storage를 선택한 다음 Quick Create를 클릭합니다.


    출처 : http://www.windowsazure.com/media/devcenter/shared/quick-storage.png

  4. URL 란에는 저장소 계정 URI의 하위 도메인으로 사용할 이름을 입력합니다. 3글자 이상 24글자 이하의 소문자나 숫자로 입력이 가능합니다. 해당 이름은 블랍(BLOB), 큐(Queue) 그리고 테이블 데이터에 접근하기 위해 사용되는 URI의 호스트 명으로 사용됩니다.
  5. REGION/AFFINITY GROUP에서 저장소의 물리적인 위치를 설정합니다. 일반적으로 Windows Azure로 프로그램을 작성한다면 해당 애플리케이션이 위치해야 할 지역에 가까운 곳을 선택하면 됩니다.
  6. CREATE STORAGE ACCOUNT를 클릭합니다.

Visual Studio에서 Windows Azure프로젝트 만들기

이번에는 비주얼 스튜디오를 사용하여 windows azure cloud 프로젝트에서 저장소 기능을 사용하는 방법에 대해 알아보도록 하겠습니다. 먼저 windows azure cloud 프로젝트를 어떻게 만드는지부터 살펴보도록 해요.

  1. .NET 용 Windows Azure SDK가 설치되어 있지 않다면 다운받아서 설치합니다.
  2. MSDN에서 "Visual Studio에서 Windows Azure 프로젝트 생성하기"를 읽고, 해당 절차에 따라서 하나 이상의 웹 롤(Web Role)이나 작업 롤(Worker Role)을 가진 Windows Azure 프로젝트를 생성합니다.

응용 프로그램에서 저장소 접근 설정하기

만들어진 프로젝트(project)의 웹 롤(web role)이나 작업 롤(worker role)은 테이블 서비스(table service)를 사용하기 위해서 필요한 대부분의 참조들을 이미 포함하고 있을 것입니다. 하지만, System.DataSerivces.Client는 수동으로 직접 추가할 필요가 있습니다.

  1. 솔루션 탐색기의 [참조]에서 마우스 오른쪽 클릭을 한다면 나오는 팝업메뉴에서 [참조 추가]를 선택합니다.
  2. .NET 탭에서 System.Data.Services.Client를 선택합니다.
  3. OK 버튼을 클릭합니다.

그 다음, Windows Azure 테이블 서비스를 사용할 C# 파일의 상단에 아래와 같은 코드를 추가합니다.

using Microsoft.WindowsAzure;
using Microsoft.WindowsAzure.StorageClient;
using System.Data.Services.Client;

Windows Azure 저장소 연결 문자열 설정하기

Windows Azure 닷넷 저장소 API는 저장소 연결 문자열을 통해서 저장소 서비스에 접근할 수 있는 끝점과 권한을 설정할 수 있도록 되어 있습니다. 그리고, 해당 연결 문자열은 프로그램 내에 하드코딩 하기 보다는 설정 파일에 넣는 것이 좋습니다.

  • Windows Cloud Azure 서비스를 사용한다면 Windows Azure 서비스 설정 파일(*.csdef와 *.cscfg)에 연결문자열을 저장하는 것이 좋습니다.
  • Windows Azure 웹 사이트나 가상머신(VM)을 이용한다면 닷넷 설정 파일(web.config 등)에 저장하는 것이 좋습니다.

2가지 경우 모두 CloudConfigurationManager 클래스의 정적 메서드인 GetSetting을 이용하여 연결 문자열을 가져올 수 있습니다.

클라우드 서비스에서 연결 문자열 설정하기

Windows Azure Cloud 서비스 프로젝트에서 서비스 설정 방식은 고유한 단일 메커니즘을 사용하기에, 설정을 변경해야 하는 경우 응용 프로그램을 재 배포하지 않고도 Windows Azure 관리 포털의 설정을 변경하는 것 만으로도 동적인 변경이 가능합니다.

이제, Windows Azure 서비스 설정에 연결 문자열을 설정해 보도록 하겠습니다.

  1. 비주얼 스튜디오의 솔루션 탐색기를 엽니다. Windows Azure 배포 프로젝트의 Roles라는 폴더를 마우스 오른쪽 클릭하거나, 웹 롤(Web Role) 또는 작업 롤(Worker Role)을 마우스 오른쪽 클릭하여 [속성]을 선택합니다.


    출처 : http://www.windowsazure.com/media/devcenter/dotnet/blob5.png

  2. Settings라는 탭을 클릭하고 Add Setting이라는 버튼을 누릅니다.
    출처 : http://www.windowsazure.com/media/devcenter/dotnet/blob6.png

    그러면 새로운 "Setting1"이라는 줄이 설정에 나타납니다.

  3. 새로 만들어진 "Setting1"이라는 줄에서 Type이라는 열의 선택박스를 Connection String으로 선택합니다.


    출처 : http://www.windowsazure.com/media/devcenter/dotnet/blob7.png

  4. 해당 줄 우측 끝에 있는 [...]이라는 버튼을 클릭합니다. 그러면 Storage Account Connection String(저장소 계정 연결 문자열)이라는 대화상자가 열립니다.
  5. 해당 창에서 로컬 컴퓨터에서 동작하는 Windows Azure 저장소 에뮬레이트(Emulator)를 선택하거나 클라우드의 실제 저장소 계정을 선택할 수 있습니다. 만일, 실제 클라우드 저장소를 사용하려 한다면 Enter storage account credentials를 선택하고 앞서 설정하였던 저장소 계정이름을 Account name에 넣은 다음 저장해 둔 Primary Access Key값을 Account key입력상자에 입력하면 됩니다.


    출처 : http://www.windowsazure.com/media/devcenter/dotnet/blob8.png

  6. 해당 줄에 Name이라는 컬럼이 "Setting1"이라고 되어 있는데 이걸 보다 직관적인 StorageConnectionString과 같은 형태로 변경합니다. 이 명칭은 나중에 나오는 예제 소스에서 사용될 것 입니다.


    출처 : http://www.windowsazure.com/media/devcenter/dotnet/blob9.png

웹사이트나 가상 머신에서 연결문자열 설정하기

웹 사이트나 가상 머신을 사용한다면 닷넷 설정 파일(web.config 등)을 이용하실 것을 추천합니다. <appSettings>에 연결 문자열을 아래와 같은 형식으로 저장할 수 있습니다.

<configuration>
  <appSettings>
    <add key="StorageConnectionString"
         value="DefaultEndpointsProtocol=https;AccountName=[AccountName];AccountKey=[AccountKey]" />
  </appSettings>
</configuration>

좀 더 자세한 정보는 연결문자열 설정하기를 참조해 주십시오.

자, 이제 How to 가이드를 공부하기 위한 준비가 완료되었습니다~~!

How To: 테이블 생성하기

CloudTableClinet 개체는 테이블과 엔티티에 대한 참조 개제를 가지고 올 수 있도록 해줍니다. 아래의 코드에서는 CloludTableClinet 개체를 생성하고 그것을 이용하여 새로운 테이블을 만들고 있습니다. 이 컬럼의 모든 코드에서는 저장소 연결 문자열을 Windows Azure 응용프로그램의 서비스 설정 파일에 저장해놓고 사용하는 것으로 가정하고 CloudStorageAccount 개체를 생성하고 있습니다.

// 연결 문자열을 통해서 저장소 계정을 가져옵니다.
CloudStorageAccount storageAccount = CloudStorageAccount.Parse(
    CloudConfigurationManager.GetSetting("StorageConnectionString"));

// 테이블 클라이언트를 생성합니다.
CloudTableClient tableClient = storageAccount.CreateCloudTableClient();

// 테이블이 존재하지 않으면 생성합니다.
string tableName = "people";
tableClient.CreateTableIfNotExist(tableName);

How To: 테이블에 엔티티 추가하기

엔티티들은 TableServiceEntity에서 파생된 클래스를 사용하여 생성된 C# 개체의 속성과 1:1로 매칭됩니다. 테이블에 엔티티를 추가하기 위해서는, 먼저 엔티티의 속성들을 정의하는 클래스부터 만들어야 합니다. 아래의 코드는 고객의 이름을 Row Key로, 성을 Partition Key로 사용하는 엔티티 클래스를 정의하고 있습니다. 엔티티의 Partition Key와 Row Key는 두 가지를 합해 해당 테이블 내에서 유일한 Key가 됩니다. 같은 Partition Key를 가진 엔티티들을 조회하는 것은 다른 Partition Key를 가진 것을 조회하는 것에 비해 빠르게 조회할 수 있습니다.

public class CustomerEntity : TableServiceEntity
{
  public CustomerEntity(string lastName, string firstName)
  {
    this.PartitionKey = lastName;
    this.RowKey = firstName;
  }

  public CustomerEntity() { }

  public string Email { get; set; }

  public string PhoneNumber { get; set; }
}

엔티티를 이용하여 테이블에 어떤 작업을 수행하려면 TableServiceContext 개체가 필요합니다. 이 개체는 클라이언트 코드에서 생성하고 접근하는 모든 테이블 엔티티들의 상태를 추적합니다. 각각의 엔티티에 대해 그에 대응되는 클라이언트 개체를 사용하는 방식은 쓰기 작업을 좀 더 효과적으로 만들어 줄 수 있는데요. 이는 실행된 작업이 저장될 때 오직 변경된 개체들만이 테이블 서비스에 반영되도록 할 수 있기 때문입니다. 아래의 코드는 GetDataServiceContext 메서드를 이용하여 TableServiceContext개체를 생성하고 있으며, 그 다음 CustomerEntity 클래스의 인스턴스도 생성하고 있습니다. 그리고, serviceContext.AddObject를 이용하여 새로운 엔티티를 테이블에 추가하고 있습니다. 이는 엔티티 개체를 serviceContext에 추가한 것일 뿐이며, 여기에 추가한다고 해서 실제로 저장소 테이블에 추가되는 것은 아닙니다. 새로운 엔티티가 테이블 서비스에 저장되도록 하기 위해서는 반드시 SaveChangesWithRetries를 호출해야만 합니다.

// 연결 문자열을 통해서 저장소 계정을 가져옵니다.
CloudStorageAccount storageAccount = CloudStorageAccount.Parse(
    CloudConfigurationManager.GetSetting("StorageConnectionString"));

// 테이블 클라이언트를 생성합니다.
CloudTableClient tableClient = storageAccount.CreateCloudTableClient();

// 데이터 서비스 컨텍스트를 가지고 옵니다.
TableServiceContext serviceContext = tableClient.GetDataServiceContext();

// 새로운 고객 엔티티를 생성합니다.
CustomerEntity customer1 = new CustomerEntity("Harp", "Walter");
customer1.Email = "Walter@contoso.com";
customer1.PhoneNumber = "425-555-0101";

// 새로운 고객을 people 테이블에 추가합니다.
serviceContext.AddObject("people", customer1);

// 테이블 서비스에 해당 동작을 전송합니다.
serviceContext.SaveChangesWithRetries();

How To: 여러 엔티티를 한번에 추가하기(배치 작업)

한번의 쓰기 동작으로 테이블 서비스에 엔티티들을 배치 처리할 수 있습니다. 아래의 코드는 3개의 엔티티 개체를 생성하고 각각을 서비스 컨텍스트에 AddObject 메서드를 사용하여 추가합니다. 그리고 SaveChangesWithRetries 메서드를 SaveChangesOptions.Batch 옵션을 설정하여 호출합니다. 만약에 SaveChangesOptions.Batch가 생략되면 3개의 각각 다른 호출이 테이블 서비스 발생합니다. 배치 처리와 관련한 주요사항을 몇 가지 살펴보겠습니다.

  1. 추가, 수정, 삭제를 배치로 수행할 수 있습니다.
  2. 한 번의 배치 처리는 엔티티를 100개까지 포함할 수 있습니다.
  3. 하나의 배치 처리의 모든 엔티티는 같은 파티션 키를 가지고 있어야 합니다.

// 연결 문자열을 통해서 저장소 계정을 가져옵니다.
CloudStorageAccount storageAccount = CloudStorageAccount.Parse(
    CloudConfigurationManager.GetSetting("StorageConnectionString"));

// 테이블 클라이언트를 생성합니다.
CloudTableClient tableClient = storageAccount.CreateCloudTableClient();
string tableName = "people";

// 데이터 서비스 컨텍스트를 가지고 옵니다.
TableServiceContext serviceContext = tableClient.GetDataServiceContext();

// 테이블에 고객 엔티티를 생성하고 추가합니다.
CustomerEntity customer = new CustomerEntity("Smith", "Jeff");
customer.Email = "Jeff@contoso.com";
customer.PhoneNumber = "425-555-0104";
serviceContext.AddObject(tableName, customer);

// 다른 고객 엔티티를 생성하고 테이블에 추가합니다.
CustomerEntity customer2 = new CustomerEntity("Smith", "Ben");
customer2.Email = "Ben@contoso.com";
customer2.PhoneNumber = "425-555-0102";
serviceContext.AddObject(tableName, customer2);

// 또 다른 고객 엔티티를 생성하고 테이블에 추가합니다.
CustomerEntity customer3 = new CustomerEntity("Smith", "Denise");
customer3.Email = "Denise@contoso.com";
customer3.PhoneNumber = "425-555-0103";
serviceContext.AddObject(tableName, customer3);

// 테이블 서비스에 해당 동작들을 제출합니다.
serviceContext.SaveChangesWithRetries(SaveChangesOptions.Batch);

How To: 동일 파티션에 속한 모든 엔티티 가져오기

단일 파티션의 모든 엔티티를 조회하기 위해서는 LINQ 쿼리를 이용합니다. 우선, serviceContext.CreateQuery를 호출하여 데이터 소스로부터 쿼리를 생성합니다. 아래의 코드는 'Smith'라는 파티션 키로 엔티티를 조회하는 예제입니다. LINQ쿼리로 실행된 결과에 대해 AsTableServiceQuery<CustomerEntity>을 호출하여 CloudTableQuery 개체를 생성합니다. 그리고, foreach 문 안에서 partitionQuery라는 개체를 사용하여 그 결과를 이용할 수 있습니다. 이 코드에서는 각각의 엔티티의 속성들을 콘솔에 출력하도록 하였습니다.

// 연결 문자열을 통해서 저장소 계정을 가져옵니다.
CloudStorageAccount storageAccount = CloudStorageAccount.Parse(
    CloudConfigurationManager.GetSetting("StorageConnectionString"));

// 연결 문자열을 통해서 저장소 계정을 가져옵니다.
CloudTableClient tableClient = storageAccount.CreateCloudTableClient();

// 데이터 서비스 컨텍스트를 가지고 옵니다.
TableServiceContext serviceContext = tableClient.GetDataServiceContext();

// "Simth"라는 파티션 키를 이용하여 특정 파티션을 질의합니다.
CloudTableQuery<CustomerEntity> partitionQuery =
    (from e in serviceContext.CreateQuery<CustomerEntity>("people")
     where e.PartitionKey == "Smith"
     select e).AsTableServiceQuery<CustomerEntity>();

// 결과에 대해 루프를 돌면서 엔티티에 대한 정보를 출력합니다.
foreach (CustomerEntity entity in partitionQuery)
{
    Console.WriteLine("{0}, {1}\t{2}\t{3}", entity.PartitionKey, entity.RowKey,
        entity.Email, entity.PhoneNumber);
}

How To: 동일 파티션의 엔티티를 일부만 가져오기

만약, 특정 파티션의 전체 엔티티가 아닌 일부를 조회하려는 경우에는 일반적으로 사용하는 ">"(..보다 큰), "<"(…보다 작은) 의 연산자 대신 CompareTo 메서드를 이용하여 일정 부분으로 한정할 수 있습니다. 전자의 구문을 사용하게 되면 변칙적인 쿼리 구조가 만들어 질 수 있기 때문입니다. 아래의 코드는 'Smith'라는 파티션에서 Row Key가 'E'까지의 문자로 시작하는 2개의 엔티티를 가져옵니다. 그리고, 그 조회 결과를 출력합니다. 만일, 여러분이 이미 앞의 Insert 배치 예제를 통해서 고객 엔티티들을 테이블에 입력해 둔 상태라면, 이번 예제의 결과로 2개의 엔티티(즉, Ben 과 Denise Smith)가 반환될 것이며, Jeff Smith는 결과에 포함되지 않을 것입니다.

// 연결 문자열을 통해서 저장소 계정을 가져옵니다.
CloudStorageAccount storageAccount = CloudStorageAccount.Parse(
    CloudConfigurationManager.GetSetting("StorageConnectionString"));

// 테이블 클라이언트를 생성합니다.
CloudTableClient tableClient = storageAccount.CreateCloudTableClient();

// 데이터 서비스 컨텍스트를 가지고 옵니다.
TableServiceContext serviceContext = tableClient.GetDataServiceContext();

// "Smith"라는 파티션키와 문자 "E"까지로 시작하는 row key로 한정된 파티션 조회입니다.
CloudTableQuery<CustomerEntity> entityRangeQuery =
    (from e in serviceContext.CreateQuery<CustomerEntity>("people")
     where e.PartitionKey == "Smith" && e.RowKey.CompareTo("E") < 0
     select e).AsTableServiceQuery<CustomerEntity>();

// 결과에 대해 루프를 돌면서 엔티티에 대한 정보를 출력합니다.
foreach (CustomerEntity entity in entityRangeQuery)
{
    Console.WriteLine("{0}, {1}\t{2}\t{3}", entity.PartitionKey, entity.RowKey,
        entity.Email, entity.PhoneNumber);
}

How To: 단일 엔티티만 가져오기

아래의 코드와 같이 2개의 조건을 사용하여 "Jeff Smith"라는 특정 고객의 단일 엔티티를 가져오는 쿼리를 작성할 수도 있습니다. 이 경우는 AsTableServiceQuery대신에 FirstOrDefault를 호출합니다. 이 메서드는 단 하나의 결과를 반환하며, 그렇기에 그 결과를 하나의 CustomerEntity 개체에 바로 할당할 수 있습니다. FirstOrDefault는 결과 값이 없는 경우에는 null를 반환합니다. 테이블 서비스로부터 하나의 엔티티를 반환받는 최적의 방법은 쿼리 상에서 파티션 키와 row key를 함께 사용하여 한정하는 것입니다.

// 연결 문자열을 통해서 저장소 계정을 가져옵니다.
CloudStorageAccount storageAccount = CloudStorageAccount.Parse(
    CloudConfigurationManager.GetSetting("StorageConnectionString"));

// 테이블 클라이언트를 생성합니다.
CloudTableClient tableClient = storageAccount.CreateCloudTableClient();

// 데이터 서비스 컨텍스트를 가지고 옵니다.
TableServiceContext serviceContext = tableClient.GetDataServiceContext();

// 파티션 키 "Smith"와 Row Key "Jeff"로 엔티티를 반환합니다.
CustomerEntity specificEntity =
    (from e in serviceContext.CreateQuery<CustomerEntity>("people")
     where e.PartitionKey == "Smith" && e.RowKey == "Jeff"
     select e).FirstOrDefault();

How To: 엔티티 수정하기

엔티티를 수정하기 위해서는 테이블 서비스로부터 엔티티 개체를 가져와서 변경한 다음, 다시 테이블 서비스에 변경된 엔티티를 저장하면 됩니다. 아래의 코드는 현재 존재하는 고객의 전화번호를 변경하고 있는데요. 앞서 고객 정보를 추가할 때 사용했던 AddObject를 사용하는 대신에 이번에는 UpdateObject를 호출하고 있습니다. 그리고, SaveChangesWithRetries 메서드를 호출하게 되면 테이블 서비스를 호출하여 엔티티를 수정하게 됩니다. 단, 현재의 응용 프로그램이 해당 정보를 가져온 이래로 다른 응용 프로그램에서 그 정보를 변경하지 않았을 경우에만 수정됩니다. 만일, 다른 응용 프로그램에서 고객 정보를 변경했다면, 예외(에러)가 발생하게 되고, 그 경우에는 엔티티를 다시 가져와서, 다시금 변경하고, 저장해야만 합니다. 이러한 재시도(retry) 패턴은 일반적으로 분산 저장소 시스템 환경에서 사용됩니다.

// 연결 문자열을 통해서 저장소 계정을 가져옵니다.
CloudStorageAccount storageAccount = CloudStorageAccount.Parse(
    CloudConfigurationManager.GetSetting("StorageConnectionString"));

// 테이블 클라이언트를 생성합니다.
CloudTableClient tableClient = storageAccount.CreateCloudTableClient();

// 데이터 서비스 컨텍스트를 가지고 옵니다.
TableServiceContext serviceContext = tableClient.GetDataServiceContext();

// 파티션 키 "Smith"와 Row Key "Jeff"로 엔티티를 반환합니다.
CustomerEntity specificEntity =
    (from e in serviceContext.CreateQuery<CustomerEntity>("people")
     where e.PartitionKey == "Smith" && e.RowKey == "Jeff"
     select e).FirstOrDefault();

// 새로운 전화번호를 입력합니다.
specificEntity.PhoneNumber = "425-555-0105";

// 해당 엔티티를 업데이트 합니다.
serviceContext.UpdateObject(specificEntity);

// 해당 엔티티를 업데이트 합니다.
serviceContext.SaveChangesWithRetries();

How To: 엔티티의 특정 속성만 조회하기

엔티티로부터 단 몇 개의 특정 속성들만을 가져올 수도 있습니다. 이런 기술을 프로젝션(Projection)이라고 하는데, 거대한 엔티티들의 경우에는 네트워크 대역폭의 감소와 조회 성능의 향상을 위해서 이 기법을 사용하는 것이 도움이 됩니다. 아래의 코드는 테이블에서 엔티티의 전자메일 주소만을 가져오고 있습니다. 프로젝션에 관해서는 다음 블로그 게시물을 통해서 더 많을 것을 배울 수 있을 것 입니다. 단, 로컬의 저장소 에뮬레이터는 프로젝션(Projection)을 지원하지 않는다는 점을 기억하십시오. 그래서, 이번 코드는 테이블 서비스 계정을 이용해서 구동하셔야 합니다.

// 연결 문자열을 통해서 저장소 계정을 가져옵니다.
CloudStorageAccount storageAccount = CloudStorageAccount.Parse(
    CloudConfigurationManager.GetSetting("StorageConnectionString"));

// 테이블 클라이언트를 생성합니다.
CloudTableClient tableClient = storageAccount.CreateCloudTableClient();

// 데이터 서비스 컨텍스트를 가지고 옵니다.
TableServiceContext serviceContext = tableClient.GetDataServiceContext();

// 전자 메일 속성만 반환하는 프로젝션(Projection) 쿼리를 정의합니다.
var projectionQuery =
    from e in serviceContext.CreateQuery<CustomerEntity>("people")
    select new
    {
        Email = e.Email
        // 추가적인 속성들은 여기에 추가하시면 됩니다.
    };

// 결과에 대해 루프를 돌면서 엔티티에 대한 정보를 출력합니다.
foreach (var person in projectionQuery)
{
    Console.WriteLine(person.Email);
}

How To: 엔티티가 없으면 추가하고 있으면 변경하기

개발을 하다보면, 테이블에 이미 특정 엔티티가 존재하고 있는지 모르는 상태에서 해당 엔티티를 추가하고자 하는 경우가 종종 있습니다. 이런 경우엔 "추가 또는 교체"라는 방식이 유리한데요. 이는 엔티티가 아직 없으면 추가하고, 이미 있으면 교체하도록 하는 작업을 단일 요청으로 처리할 수 있게 하는 기법입니다. 다음의 코드는 이전의 예제를 기반으로 하여 "Walter Harp"라는 엔티티를 추가 또는 교체하는 코드입니다. 코드에서는 우선 새로운 엔티티를 생성한 다음, serviceContext.AttachTo 메서드를 호출하고 있습니다. 그런 다음, UpdateObject를 호출하고 마지막으로 SaveChangesWithRetries를 SaveChangesOptions.ReplaceOnUpdate라는 옵션과 함께 호출합니다. SaveChangeOptions.ReplaceOnUpdate라는 옵션을 생략하게 되면 "추가 또는 교체"가 아닌 "추가 또는 병합" 동작이 일어나게 됩니다. "추가 또는 교체"와 "추가 또는 병합"에 관해서 좀더 알고 싶다면 이 블로그 게시물을 참고해 주십시오. 그리고, "추가 또는 교체" 동작 또한 로컬 저장소 에뮬레이터에서는 지원되지 않으며, 테이블 서비스 계정을 통해서만 실행하실 수 있다는 점을 기억하시기 바랍니다.

// 연결 문자열을 통해서 저장소 계정을 가져옵니다.
CloudStorageAccount storageAccount = CloudStorageAccount.Parse(
    CloudConfigurationManager.GetSetting("StorageConnectionString"));

// 테이블 클라이언트를 생성합니다.
CloudTableClient tableClient = storageAccount.CreateCloudTableClient();

// 데이터 서비스 컨텍스트를 가지고 옵니다.
TableServiceContext serviceContext = tableClient.GetDataServiceContext();

// 새로운 고객 엔티티를 생성합니다.
CustomerEntity customer5 = new CustomerEntity("Harp", "Walter");
customer5.Email = "Walter@contoso.com";
customer5.PhoneNumber = "425-555-0106";

// 새로운 고객정보를 people 테이블에 Attach하기
serviceContext.AttachTo("people", customer5);

// 새로운 고객정보를 people 테이블에 Attach하기
serviceContext.UpdateObject(customer5);

// 테이블 서비스에 해당 동작을 ReplaceOnUpdate 옵션을 주어 제출합니다.
serviceContext.SaveChangesWithRetries(SaveChangesOptions.ReplaceOnUpdate);

How To: 엔티티 삭제하기

엔티티를 반환 받은 후 쉽게 삭제 할 수 있습니다. 그리고 위의 "추가 또는 교체" 에서처럼 AttachTo 메서드를 이용하여 서버로부터 엔티티를 반환 받지 않고 serviceContext에 기록하여 삭제할 엔티티와 함께 DeleteObject를 호출하고 SaveChangesWithRetries를 호출하는 방법도 있습니다. 아래의 코드는 고객 엔티티를 반환 받고 삭제하는 것입니다.

// 연결 문자열을 통해서 저장소 계정을 가져옵니다.
CloudStorageAccount storageAccount = CloudStorageAccount.Parse(
    CloudConfigurationManager.GetSetting("StorageConnectionString"));

// 테이블 클라이언트를 생성합니다.
CloudTableClient tableClient = storageAccount.CreateCloudTableClient();

// 데이터 서비스 컨텍스트를 가지고 옵니다.
TableServiceContext serviceContext = tableClient.GetDataServiceContext();

CustomerEntity specificEntity =
    (from e in serviceContext.CreateQuery<CustomerEntity>("people")
     where e.PartitionKey == "Smith" && e.RowKey == "Jeff"
     select e).FirstOrDefault();

// 엔티티를 삭제합니다.
serviceContext.DeleteObject(specificEntity);

// 테이블 서비스에 해당 동작을 제출합니다.
serviceContext.SaveChangesWithRetries();

How To: 테이블 삭제

마지막으로 아래의 예제를 통해서 저장소 계정에 있는 테이블을 삭제해보도록 하겠습니다. 테이블이 삭제되는 동안에는 일정 시간동안(체감상 수십 초에서 몇 분 정도) 동일한 이름의 테이블은 재생성이 불가능합니다.

// 연결 문자열을 통해서 저장소 계정을 가져옵니다.
CloudStorageAccount storageAccount = CloudStorageAccount.Parse(
    CloudConfigurationManager.GetSetting("StorageConnectionString"));

// 테이블 클라이언트를 생성합니다.
CloudTableClient tableClient = storageAccount.CreateCloudTableClient();

// 해당 테이블 존재하면 삭제합니다.
tableClient.DeleteTableIfExist("people");

다음으로 볼 내용들

이제 여러분들은 테이블 저장소에 관한 기본적인 내용들을 배웠습니다. 좀 더 복잡한 저장소 관련 작업은 아래의 링크들을 통해서 배울 수 있습니다.


authored by


 
 
.NET과 Java 동영상 기반의 교육사이트

로딩 중입니다...

서버 프레임워크 지원 : NeoDEEX
based on ASP.NET 3.5
Creative Commons License
{5}
{2} 읽음   :{3} ({4})