( 조심 : 이 정보는 직접 Coding을 해서 얻은 결과 입니다. 실제 Azure 아키텍처를 명확히 이해하여 쓴 글은 아닙니다. )

Windows Azure에서 데이터를 저장하는 방식은 Table 기반의 저장 방식을 따른다.
물론 Azure 서비스 중 하나인 SQL 서비스를 직접 이용하는 방법이 있지만,
사실 그 방법 말고도, .NET 3.5 에서 제공하는 LINQ 방식을 이용하여 만드는 방법이 있다.
그리고 현재 Windows Azure Platform Kit ( 11월 버전 ) 에 담긴 Hands on Lab을 하다 보면,
이렇게 구성하는 구나, 싶다.


1. 데이터 저장을 위한 Table 구성

데이터의 기본은 표. 즉 Table 이다. 그리고 그 Table에 데이터를 쌓는 것을 레코드 혹은 Row 라고 한다.
그리고 각 데이터의 종류를 나타내는 것을 필드 혹은 Column 이라고 한다.

Table

  Column  
Row ->    
     
     

여기서는 위의 구조 중 Row와 Table을 구현하여 데이터를 구성하게 된다.

먼저 Table을 역할을 하는 Data 기본 셋으로 Windows Class Library 프로젝트를 하나 생성한다.
즉 Table이 여러 개 필요하면 그에 맞추어 프로젝트를 생성하면 된다.
( 이 부분은 나중에 Azure 문서 중 Data 관련된 사항을 더 공부하고 정리할 예정이다.)

즉 필요한 Table 만큼의 Windows Class Library 프로젝트를 생성하도록 한다.( Hands on Lab에서는 방명록을 구현하는데 그 때 사용되는 데이터를 구성하기 위해 하나의 Class Library 프로젝트를 만드는데 바로 그게 데이터 저장을 위한 Table 역할을 하게 된다. )

단 .NET Framework 3.5 이상 용으로 만들어야 한다.
    그래서 개발 환경 조건에, Visual Studio 2008 이상이 필요한 것이다.


이 때 프로젝트에는 다음과 같은 어셈블리를 Reference 해야 한다.

System.Data.Services.Client   ( .NET Framework 3.5 )
Microsoft.WindowsAzure.StorageClient   ( Azure SDK )

일단 위의 레퍼런스가 끝났다면 이제 Row을 구성한다.

2. 데이터 구조 잡기 가장 기초 부분 Entity

위에서 언급한 Row 부분 – 관점을 조금 돌리면 Column을 구성하는 것? 이라고 볼 수도 있다. - 을 구성하는 방법이다. 어떤 데이터를 어떻게 저장할 것인지를 결정하는 부분이다.
방법은 다음과 같다.

  1. public 클래스를 만든다.
  2. Microsoft.WindowsAzure.StorageClient.TableServiceEntity 를 상속 받는다.
  3. 생성자를 만든다.
  4. 생성자 안에 PartitionKey 와 Row Key를 설정한다.
  5. 프로퍼티를 만든다.

위의 다섯 단계를 찬찬히 설명하면 아래와 같다.

1과 2는 C#의 기초 단계와 다름이 없을 것이다.
일단 using을 써서 Microsoft.WindowsAzure.StorageClient 를 추가하는 줄을 넣는다.

using System;
using Microsoft.WindowsAzure.StorageClient;

그리고 난 뒤에, class 앞에 public 넣고, 맨 뒤에 : 을 넣은 뒤, TableServiceEntitiy를 넣는다

using System;
using Microsoft.WindowsAzure.StorageClient;

namespace GuestBook_Data
{
    public class GuestBookDataEntry : TableServiceEntity
    {

    }

}

위의 단계까지 왔으면 일단 기본은 끝난 것이다.

3~4 번 단계에서는 생성자를 생성하고, 그 안에 고유의 값을 넣는 작업을 한다.
단 기본 생성자로 생성해준다. 그리고, 이 GuestBookDataEntry 클래스는 프로젝트 밖에서  new 해야 되기 때문에, 이 생성자를 반드시 public으로 선언해야 한다. 
생성자 안에서  PartitionKey와 RowKey에 고유의 값을 넣어주도록 한다.
RowKey는 모든 데이터에서도 가장 유일한 값이여야 한다는 것은 이해했지만, PartitionKey는 DB의 Partition 과 유사한 기능 같았다. 그래서 이 부분은 그냥 다른 Table과 구분되는 정도의 레벨의 데이터로 생각하여 넣었다. PartitionKey 는 알아서.. 잘 넣어주시면 될 것 같다.

using System;
using Microsoft.WindowsAzure.StorageClient;

namespace GuestBook_Data
{
    public class GuestBookDataEntry : TableServiceEntity
    {
        public GuestBookDataEntry()
        {
            PartitionKey = "GuestBookRawData";

            RowKey = string.Format("{0:10}_{1}", DateTime.MaxValue.Ticks - DateTime.Now.Ticks, Guid.NewGuid());
        }
    }
}


5번 단계에서는 실제 값이 어떻게 들어갈지를 정의하면 된다.

using System;
using Microsoft.WindowsAzure.StorageClient;

namespace GuestBook_Data
{
    public class GuestBookDataEntry : TableServiceEntity
    { 
       public String Name { get; set; }
        public String Email { get; set; }
        public String HomePage { get; set; }
        public DateTime writtenDate { get; set; }

        public GuestBookDataEntry()
        {
            PartitionKey = "GuestBookRawData";

            RowKey = string.Format("{0:10}_{1}", DateTime.MaxValue.Ticks - DateTime.Now.Ticks, Guid.NewGuid());
        }
    }
}

C# 3.0 에서 사용되는 프로퍼티의 기본형으로 써주면 된다.
public으로 정의하고 그 데이터 형을 결정한 뒤, get과 set을 정의해주면 된다.
( C# 3.0에서 보면, 프로퍼티에서 그냥 get;set; 을 써주면 알아서 저장된다. )

아직은 기본형만 써봐서, 다른 형태의 Class 데이터나 복합형 데이터는 만들어보지는 않았다.
일단, 위와 같은 형태로 구성한다.

그러면 기본적인 Row 가 정의된다.

3. Context 구성하기.

데이터의 입출력을 할 때, 그 흐름을 정의하는 부분이라고 보면 된다.
어디서 저장되고, 어디로 저장되며 어떻게 진행되는지. 그러나, 실제로의 구현은 모두 기본값 만을 이용하여 생성할 예정이다. 그러므로 코드는 무척 간단하다.

using System;
using System.Linq;
using Microsoft.WindowsAzure;
using Microsoft.WindowsAzure.StorageClient;

namespace GuestBook_Data
{
    public class GuestBookDataContext : TableServiceContext
    {
        public GuestBookDataContext(string baseAddress, StorageCredentials credentions)
            : base(baseAddress, credentions)
        {
        }

        public IQueryable<GuestBookDataEntry> GuestBookDataEntry
        {
            get
            {
                return this.CreateQuery<GuestBookDataEntry>("GuestBookDataEntry");
            }
        }
    }
}

위의 코드 중 굵은 부분만 구성해주면 된다. 그런데, 저 붉은 부분은 좀 신경써서 정리해주어야 한다.
만일 저 붉은 내용의 문자열이 조금이라도 틀리면 알기 힘든 오류를 내어 디버깅 자체가 어려워 질 수 있다.
반드시 저 붉은색 부분은 신경써서 넣어주기 바란다. 저 붉은 부분에 넣는 것은 앞서 선언한 Entity 에 대한 Class 이름이다.

4. 데이터 접근용 Class.

사실 위의 두개의 class만 있어도 기본적인 데이터 접근은 가능하다. 하지만, 외부에서 데이터 호출을 위한 로직을 직접 선언하여 구축하는건 조금 지저분 해지기 때문에, 가급적 이런 대리자의 역할을 하는 클래스 구성이 효율적일 수 있다.

이 클래스는 굳이 상속 받을 필요는 없다. 생성 한 뒤, 데이터를 쿼리하거나 데이터를 넣는 정도의 인터페이스만 제공하면 되는 클래스 이기 때문이다.

먼저 Skelton 코드로는 다음과 같다.

using System;
using System.Linq;
using System.Collections.Generic;
using Microsoft.WindowsAzure;
using Microsoft.WindowsAzure.StorageClient;

namespace GuestBook_Data
{
    public class GuestBookDataSource
    {
        private static CloudStorageAccount storageAccount;
        private LottoSvcDataContext context;

        static GuestBookDataSource()
        {
            storageAccount = CloudStorageAccount.FromConfigurationSetting("DataConnectionString");

            CloudTableClient.CreateTablesFromModel(
                typeof(GuestBookDataContext),
                storageAccount.TableEndpoint.AbsoluteUri,
                storageAccount.Credentials);
        }

        public GuestBookDataSource()
        {
            this.context = new GuestBookDataContext(storageAccount.TableEndpoint.AbsoluteUri, storageAccount.Credentials);
            this.context.RetryPolicy = RetryPolicies.Retry(3, TimeSpan.FromSeconds(1));
        }

    }
}

위에서 보는 것과 같이 생성자를 두 개 만든다.

둘 다 생성자이기는 하지만 그 역할을 판이하게 다르다. static 으로 선언한 생성자는 프로그램이 시작할 때 new 하던지 말던지 1회성으로 무조건 1번 실행하는 단발성 생성자다. 여기서는 앞서 만든 테이블 구조에 따라 가상의 테이블을 만들어주는 역할을 하게 된다.

그리고 두번째에 위치한 생성자는 일반적인 생성자로, 실제 이 데이터 관련 작업을 수행할 때 new 해서 생성하면 불리는 생성자다.

그리서 첫번째의 static 생성자에서는 CloudStorage 관련 도구를 사용하여 Table을 실제적인 인스턴스를 생성하는데 그 역할을 다하며, 두번재의 일반 생성자에서는 그 만들어진 Table에 접속하기 위한 기초적인 내용이 담기게 된다. 이 때, Static 생성자에서 사용하는 DataConnectionString 부분을 주목하자.
저 문자열이 뜬금없이 나온 문자열은 아니다. 분명 누군가가 저 값을 가져왔기에 그 내용을 쓸 수 있는 것이다.

저 내용은 이 DataSource를 New 해서 만들어서 사용하는 주체인 Web-Role 혹은 Worker-Role의 옵션에서 설정하게 된다. 이에 대한 설명은 나중에, 그냥 설정하는 방법은 다음과 같다.

  1. Solution Explorer 안에서 Service 목록이 나오는 곳을 찾는다. ( Azure 프로젝트로 만듦면 특이한 아이콘으로 생긴 프로젝트가 보인다 )
  2. 그 중에 설정하려고 하는 Role 부분에서 오른쪽 버튼을 클릭한다.
  3. 속성 창이 뜨면, 왼쪽 항목 Tab에서 Settings를 선택하고 AddString을 한 뒤, Name에 DataConnectionString을 넣고, Type은 ConnectionString을 Value는 그냥 기본값을 둔다. ( 기본값으로 하면, 로컬 DB에 저장하겠다는 의미 )

일단 이 DataSource 라는 것을 사용하는게 Web-Role이라는 가정하예서, Web-Role에 있는 설정을 변경하는 작업을 나타낸다.

일단 여기까지.
실제 DataSource 의 Select, Insert, Update, Delete 구현은 다음으로~

728x90
  • 어제는 들어가자마자 자서 경기 결과를 알 수 없넹(me2dayzm 월드컵)2009-06-18 10:06:41
  • 맨유경기 한국초대전 무료티켓 700장 뿌린다는데. 조건이 뭘까나(me2dayzm 맨유 무료티켓)2009-06-18 10:08:05
  • 베트남 아줌마 한국말 잘하는 편이라도 알아듣기 힘들군 내 일본 발음이 바로 저런 거 아닐까?(me2dayzm)2009-06-18 10:09:10
  • 구글맵 덕을 가끔보넹(me2dayzm 구글맵)2009-06-18 10:09:40
  • 오늘은 완존 지각. ㅋㅋ(me2dayzm 지각대장)2009-06-18 10:10:20
  • 인사 평가에 대한 고려,기대심 무엇하나 없네. 하는데 까지 절ㄹ 열심히.(me2dayzm)2009-06-18 10:11:18
  • 트위터가 알고 보니 오바마 부터 다양한 계층들이 이용중이라는 군요. 울나라에서는 김연아 효과덕으로 유명세 탔다고 하던데. 뭐니 해도 유명한 자가 한번 들이 밀어줘야…뭔가 있어보이는 지도 모르겠네요.(트위터 김연아 효과 뭐 나쁘진 않은데 뭔가 모르겠지만 낯설다는 느낌)2009-06-18 15:38:23
  • 오늘 틈새라면 안 매웠다. 잘못 만든듯(me2dayzm)2009-06-18 19:11:14
  • 어느새 목요일 내일만 지나면 다시 한 주 쫑(me2dayzm 주말D-1)2009-06-18 19:12:12
  • 양아들이은, 형광빛 카울한 택트에 큼직허니 음악틀때 안 쪽팔린가?(me2dayzm 이해하기 힘든 양아 머리 구성)2009-06-18 19:14:10
  • 일 할때 쓸 슬리퍼 하나 사야겠다.(me2dayzm)2009-06-18 19:16:15
  • 오늘은 핸폰으로 전환.(모바일 모드 에서 핸폰 모드로)2009-06-19 11:39:44
  • Azure 서비스로 만들려는 서비스나 만들어야 겠다.(azure 서비스 클라우드 컴퓨팅)2009-06-19 11:43:29
  • 다음 주 정도에 만들어놓은 프로그램의 결과나 봐야 겠다.2009-06-19 11:43:50
  • 지식 산업 인프라 구축에 요즘 유행한다는 방법론을 무조건 도입하기 전에, 눈에 보이는 무언가를 만들고 난 뒤에 하나씩 변경하는게 옳지 않을까?2009-06-19 11:53:18
  • 오늘 묘하니 비 올 분위기(me2sms)2009-06-19 12:31:54
  • 정치가들의 말바꾸기는 정말이지 신뢰안가게 만드는 주요한 원인.2009-06-19 12:50:26
  • 애저서비스 괜찮은것 같다 한번은 해볼만 한듯(me2sms)2009-06-19 14:24:40
  • 친구 꼬셔가가 애저 해볼까나?(me2sms)2009-06-19 14:27:44
  • 왠지 100건 다 안쓰믄 돈 날리는 기분 드는건 나만일까?(me2sms)2009-06-19 14:29:16
  • 장실에서 일보면서 전화허긴 글코,역쉬 미투질 뿐 인듯(me2sms)2009-06-19 14:30:51
  • 그르나 역시 일반 핸폰은 문자보내기가 영 껄끄럽다는….(me2sms)2009-06-19 14:32:28
  • 칵 옆사로에 비 맞은 중이 있다!! ㄷㄷㄷ(me2sms)2009-06-19 14:40:36
  • ASP.NET으로 프로젝트 열어봐야 겠다 익스프레 버젼도 될까?(me2sms)2009-06-19 14:55:22
  • 에쟈 잘만 구성하면 나름 도움이 될듯. 자바에 뜻이 있다면 구글 쪽에 그런 서비스가 있다고 들었다(me2dayzm)2009-06-19 19:02:46
  • 오늘은 하루종일 머리도 아프고 몸도 피곤했다(me2dayzm)2009-06-19 19:03:37
  • 콧잔등에 종기같은게 나는 바람에 안경 쓰는게 스트레스가 되버렸다(me2dayzm)2009-06-19 19:04:33
  • 오늘 하루 그저 그렇다(me2dayzm)2009-06-21 23:46:26
  • 내일은 무슨 일이 시작되고 마무리 져질까?(me2dayzm)2009-06-21 23:47:19
  • 통신이 안된다는데 무슨뜻일까?(me2dayzm)2009-06-22 05:22:39
  • 나에게서 일관성이 사라지다.2009-06-22 10:33:50
  • 조용히 있고 싶다.2009-06-22 10:34:27
  • 하지만, 끊임 없이 나오는 소리는 내야 된다.2009-06-22 10:34:44
  • 스트레스에 취약한 나로써는 명상으로써 스트레스를 흘릴 뿐.2009-06-22 10:35:07
  • 아니면 새로운 무언가를 쫒아 주변을 잊는 수 밖에…2009-06-22 10:35:32
  • 무대위의 광대 느낌. 우울증 초기 증세인가.(무언가 공허하니 울적하다 주변이 너무 시끄럽다)2009-06-22 10:43:07
  • 애자일이 먼지 아니?2009-06-22 13:40:44
  • 그럼 스크럼은? 먜한가지?2009-06-22 13:41:27
  • 인생 변화하듯 소프트웨어도 계획대로 잘 안되서 생각해낸게 그거 같은데…2009-06-22 13:42:50
  • 난 애자일 실패한 프로젝트를 봐서 그런지 약간 부정적이넹2009-06-22 13:43:39
  • 하지만 당신 같이 탑다운 방식에 약한 사람 한텐 중요한 방식일거 같은디..2009-06-22 13:45:07
  • 호들갑 좀 떨지 말고… 좀.2009-06-22 14:11:33

이 글은 하인도님의 2009년 6월 18일에서 2009년 6월 22일까지의 미투데이 내용입니다.

728x90

+ Recent posts

728x90