관계형 순위표 참조 아키텍처

아키텍처 다이어그램

관계형 데이터베이스 순위표 사용 사례

아키텍처 서비스

아키텍처 고려 사항

이 참조 아키텍처에서는 하나 이상의 게임 차원 및 기간에서 최고 경쟁자의 게임 플레이어 이름 및 집계 순위를 표시하는 "순위표"를 정의합니다.

이 참조 아키텍처는 다음과 같은 대규모 요구 사항을 전제로 합니다.

  • 100만 명의 플레이어가 매일 4개의 게임을 플레이. 이는 다음과 같이 환산됩니다.
    • 매일 400만 개의 게임(초당 ~ 46개의 게임)
    • 매월 ~ 1억 2,100만 개의 게임
    • 매년 ~ 14억 6,000만 개의 게임
  • 게임 완료 시 플레이어에게 최종 개별 게임 점수가 즉시 제공되어야 합니다.
  • 플레이어는 순위에 따라 매일 보상을 받고, 순위를 정의하는 데 사용된 전역 순위표는 4분마다 쉽게 새로 고쳐져야 합니다(충분한 실행 시간 버퍼로 실행해야 함).
  • 게임 기록이 정기적으로 "실행 부하 과다 경로"를 통해 보관되어야 합니다. 보관은 속도가 빠르고 동시 게임 결과 활동에 영향을 주지 않아야 합니다. 또한 이 참조 아키텍처의 데이터 계층은 하나 이상의 플랫폼(Xbox, PlayStation, Desktop, iOS, Android 등)에서 액세스할 수 있는 단일 게임을 커버한다고 가정합니다.

이 참조 아키텍처를 확장하여 여러 게임을 지원할 수 있지만, 게임별 격리는 개별 테넌트 확장에 도움이 되고 인접 라우터 "소음" 및 동시성 문제를 방지할 수 있습니다.

게임 순위표 성능 및 확장성을 위한 서비스 계층

게임 시작 및 지속적 대규모 처리량에 충분한 리소스를 확보하기 위해 프리미엄 또는 중요 비즈니스용 서비스 계층 모델에서 데이터 계층을 구현할 것을 고려합니다. 이러한 서비스 계층은 기본 SSD 저장소로부터 낮은 대기 시간 응답을 요구하고 기본 인프라가 실패하는 경우 빠른 복구를 제공하는 게임을 위해 설계되었습니다. 중요 비즈니스용 서비스 계층에서는 기본 데이터베이스의 무료 읽기 기능 보조 복제본을 사용할 수 있습니다.

참고

이 아키텍처에서 권장하는 모든 스키마 및 쿼리는 Azure SQL Database 중요 비즈니스용 Gen 5 서비스 계층(14개 vCores 코어)에서 16억 행의 게임 점수 기록을 사용하여 테스트되었습니다.

데이터베이스 스키마

이 참조 아키텍처의 목적을 위해 다음과 같은 기본 테이블 및 지원 제약 조건 및 인덱스를 사용합니다. 각 테이블은 "실행 가능한 최소" 스키마를 다루며 게임 요구 사항에 따라 확장될 수 있습니다.

R관계형 데이터베이스 순위표 스키마

이 스키마는 다음과 같은 사용 사례에 적합합니다.

  • 각 게임 완료 시 최종 레벨 및 점수를 GameCompletion 테이블에 삽입합니다. 이 테이블은 특히 새 행 삽입과 주기적인 순위표 스냅샷 순위 결과 계산을 위해 액세스해야 합니다.
  • GameCompletion 테이블에는 이상적으로 데이터 "실행 부하 과다 경로"에 대한 모든 행(순위 계산에 자주 사용할 것으로 예상하는 데이터)이 포함되어 있습니다. 자주 액세스하지 않는 오래된 데이터의 경우 GameCompletionHistory 테이블을 사용합니다. 이 참조 아키텍처에서는 GameCompletion에서 오래된 데이터를 제거하는 데 걸리는 시간을 최소화하기 위해 빠른 파티션 전환의 이점을 활용하는 방법을 보여줍니다. 나중에 설명할 GameCompletion 파티션 함수 및 스키마는 효율적인 데이터 보관에 도움이 됩니다.
  • GamePlatformPlayer 테이블에는 보조 게임 플랫폼 및 플레이어 관련 데이터가 포함됩니다. 이 데이터는 GameCompletion 및 GameCompletionHistory 테이블에 조인할 수 있습니다.
  • LeaderboardSnapshot 테이블에는 계산된 순위표 순위 결과가 포함됩니다.
    • 이것은 애플리케이션에서 순위 지정 결과를 반환하는 데 사용해야 하는 테이블입니다.
    • 이 테이블은 필요한 일정 및 빈도(예: 4분마다 현재 일별 순위표 순위 계산)를 기반으로 하는 별도 프로세스를 통해 채워야 합니다.
    • 데이터는 GameCompletion 테이블, 그리고 필요에 따라 GameCompletionHistory 테이블을 사용하여 계산됩니다.
    • 결과에 액세스하려면 항상 LeaderboardSnapshot 테이블을 사용합니다(GamePlatform에서 동일한 순위 결과를 반복해서 다시 계산하지 않음).
  • RankResultType 테이블에는 게임에 필요한 여러 유형의 순위표 스냅숏이 포함됩니다. 그런 다음 LeaderboardSnapshot에서 이 테이블의 기본 키를 사용하여 검색할 순위 지정 결과 유형을 나타낼 수 있습니다.

다음 섹션에서는 앞서 언급한 각 개체의 스키마에 대해 자세히 설명합니다.

Player 테이블

이 테이블에는 최적의 조인 성능을 위해 플레이어 "자연 키" 및 별칭 열에 대해 생성된 플레이어 서로게이트 키가 포함되어 있습니다.

참고

자연 키는 "실제 세계" 특성을 기반으로 하는 고유 키입니다(예: Xbox Live ID).

서로게이트 키는 고유한 시스템 생성 키입니다. 이 키 형식은 본질적으로 실제 의미는 없지만 성능을 최적화하는 데 사용할 수 있고(최적 키 데이터 형식을 선택할 수 있음), 나중에 자연 키 변경에 대한 종속성도 최소화할 수 있습니다. 예를 들어, 게임 플레이어가 Live ID를 변경하는 경우, 서로게이트 키를 사용하면 모든 플레이어 게임 기록에 필요한 여러 가지 자연 키 변경 대신 Player 테이블에 대한 변경 사항 하나만 필요합니다.

Microsoft는 핵심 게임 인증 데이터 소스 및 시스템을 기반으로 데이터를 채웁니다.

CREATE TABLE dbo.Player
(
    PlayerSurrogateKey BIGINT IDENTITY(1, 1) PRIMARY KEY CLUSTERED,
    PlayerNaturalKey UNIQUEIDENTIFIER NOT NULL,
    PlayerGamerAlias NVARCHAR(256) NOT NULL
);
GO

GamePlatform 테이블

이 테이블은 특정 게임을 재생할 수 있는 플랫폼(예: Xbox, iOS, Android)을 커버합니다.

CREATE TABLE dbo.GamePlatform
(GamePlatformSurrogateKey BIGINT IDENTITY(1,1) PRIMARY KEY CLUSTERED,
 GamePlatformName NVARCHAR(256) NOT NULL
);
GO

INSERT dbo.GamePlatform
(GamePlatformName)
VALUES (N'Xbox'), (N'iOS'), ('PS'), ('Android');
GO

GameCompletion 파티션 함수 및 스키마

가능한 경우 모든 대규모 테이블에서 분할이 가능해야 합니다. 그러면 시간이 지남에 따라 보관하고 "cold path" 데이터를 위해 확장할 수도 있습니다. 다음 파티션 함수 및 스키마는 연속 테이블 예제에 사용됩니다. 이 예제에서는 2019년 각 월에 대한 분할이 수행 되며, 게임 요구 사항 및 데이터 보존 정책에 따라 기간을 연장(분할 및 병합)할 수 있습니다.

CREATE PARTITION FUNCTION GameCompletionMonthPartitionFunction (DATETIME2)
AS RANGE RIGHT FOR VALUES
(   '20190201',
    '20190301',
    '20190401',
    '20190501',
    '20190601',
    '20190701',
    '20190801',
    '20190901',
    '20191001',
    '20191101',
    '20191201'
);
GO

CREATE PARTITION SCHEME GamePartitionMonthPartitionScheme
AS PARTITION GameCompletionMonthPartitionFunction
ALL TO
    (
        [PRIMARY]
    );
GO

GameCompletion 테이블

GameCompletion 테이블은 레벨, 게임 완료 날짜, 플레이어 및 게임 플랫폼별 최종 점수로 채워집니다. 이 테이블은 게임 완료 날짜에 따라 분할됩니다.

CREATE TABLE dbo.GameCompletion
(
    GameCompletionSurrogateKey BIGINT IDENTITY(1, 1),
    PlayerSurrogateKey BIGINT NOT NULL,
    GamePlatformSurrogateKey BIGINT NOT NULL,
    GameCompletionLevel INT NOT NULL,
    GameCompletionScore BIGINT NOT NULL,
    GameCompletionDate DATETIME2 NOT NULL
) ON GamePartitionMonthPartitionScheme (GameCompletionDate);
GO

또한 매우 큰 결과 집합에 대해 짧은 대기 시간 순위 분석 쿼리를 사용하기 위해 이 테이블에 클러스터형 columnstore 인덱스를 추가합니다.

CREATE CLUSTERED COLUMNSTORE INDEX CCI_GameCompletion
ON dbo.GameCompletion
ON GamePartitionMonthPartitionScheme(GameCompletionDate);
GO

데이터 품질을 지원하기 위해 다음 기본 키와 두 개의 외래 키 제약 조건을 이 테이블에 추가합니다.

ALTER TABLE dbo.GameCompletion
ADD CONSTRAINT PK_GameCompletionOriginal
    PRIMARY KEY NONCLUSTERED (
                                 GameCompletionSurrogateKey,
                                 GameCompletionDate
                             ) ON GamePartitionMonthPartitionScheme(GameCompletionDate);
GO

ALTER TABLE dbo.GameCompletion
ADD CONSTRAINT FK_GameCompletion_PlayerSurrogateKeyOriginal
    FOREIGN KEY (PlayerSurrogateKey)
    REFERENCES dbo.Player (PlayerSurrogateKey);
GO

ALTER TABLE dbo.GameCompletion
ADD CONSTRAINT FK_GameCompletion_GamePlatformSurrogateKeyOriginal
    FOREIGN KEY (GamePlatformSurrogateKey)
    REFERENCES dbo.GamePlatform (GamePlatformSurrogateKey);
GO

GameCompletion 테이블에 대한 임시 활동을 최소로 유지합니다. 이 테이블은 수신 점수 행(~ 50행/초)을 빠르게 주입하는 데 사용해야 합니다. 결과에 순위를 지정하기 위해 GameCompletion에 액세스하는 대신, 모든 대고객 보고 및 애플리케이션 계층 캐싱에 LeaderboardSnapshot 테이블을 사용합니다.

GameCompletionHistory 테이블

GameCompletionHistory 테이블은 액세스의 "cold path"에서 기록 행을 보유하기 위한 것입니다. GameCompletion 테이블의 기본 파티션 스키마와 일치하는 이러한 기록 테이블을 유지하는 것이 좋습니다. 그러면 GameCompletion에서 GameCompletionHistory로 빠른 파티션 전환이 가능합니다(이에 대해서는 나중에 설명).

CREATE TABLE dbo.GameCompletionHistory
(
    GameCompletionSurrogateKey BIGINT NOT NULL,
    PlayerSurrogateKey BIGINT NOT NULL,
    GamePlatformSurrogateKey BIGINT NOT NULL,
    GameCompletionLevel INT NOT NULL,
    GameCompletionScore BIGINT NOT NULL,
    GameCompletionDate DATETIME2 NOT NULL
) ON GamePartitionMonthPartitionScheme (GameCompletionDate);
GO

CREATE CLUSTERED COLUMNSTORE INDEX CCI_GameCompletionHistory
ON dbo.GameCompletionHistory
ON GamePartitionMonthPartitionScheme(GameCompletionDate);
GO

ALTER TABLE dbo.GameCompletionHistory
ADD CONSTRAINT PK_GameCompletionHistory
    PRIMARY KEY NONCLUSTERED (
        GameCompletionSurrogateKey,
        GameCompletionDate
    ) ON GamePartitionMonthPartitionScheme(GameCompletionDate);
GO

RankResultType 테이블

RankResultType 테이블에는 게임에 대해 생성하려는 순위 범주가 포함됩니다. 아래 예제에서는 모든 시간, 일, 주, 월 및 년에 대한 순위가 있습니다. 실제 순위표 결과에서 이를 별도의 테이블에 참조하도록 하면 이후 순위 옵션의 확장성이 확보됩니다.

CREATE TABLE dbo.RankResultType
(
    RankResultTypeSurrogateKey SMALLINT IDENTITY(1, 1) PRIMARY KEY CLUSTERED,
    RankResultTypeDescription NVARCHAR(256) NOT NULL
);
GO

INSERT dbo.RankResultType
(
    RankResultTypeDescription
)
VALUES
('All Time'),
('Day'),
('Week'),
('Month'),
('Year');
GO

LeaderboardSnapshot 테이블

LeaderboardSnapshot 테이블에는 잠재적 순위 유형 배열에 대한 지정 시간 순위표 순위 결과가 포함됩니다. 이렇게 하면 원본 점수 데이터에서 순위를 반복적으로 다시 계산하지 않고도 최신 또는 과거 결과에 대해 반복해서 액세스할 수 있습니다. 또한 순위 결과 형식에 외래 키 제약 조건을 추가합니다. 또한 더 편리한 계산 후 디버깅을 지원하기 위해 원래 점수 테이블에서 일부 열이 유지됨을 확인할 수 있습니다(지정 시간 레벨, 점수, 날짜를 유지).

CREATE TABLE dbo.LeaderboardSnapshot
(
    PlayerSurrogateKey BIGINT NOT NULL,
    GamePlatformSurrogateKey BIGINT NOT NULL,
    LeaderboardSnapshotDate DATETIME2 NOT NULL,
    GameCompletionLevel INT NOT NULL,
    GameCompletionScore BIGINT NOT NULL,
    GameCompletionDate DATETIME2 NOT NULL,
    RankResultTypeSurrogateKey SMALLINT NOT NULL,
    RankResult BIGINT NOT NULL,
    CONSTRAINT PK_LeaderboardSnapshot
        PRIMARY KEY CLUSTERED (
            PlayerSurrogateKey,
            GamePlatformSurrogateKey,
            LeaderboardSnapshotDate,
            GameCompletionDate,
            RankResultTypeSurrogateKey
        )
);
GO

ALTER TABLE dbo.LeaderboardSnapshot
ADD CONSTRAINT FK_LeaderboardSnapshot_PlayerSurrogateKey
    FOREIGN KEY (RankResultTypeSurrogateKey)
    REFERENCES dbo.RankResultType (RankResultTypeSurrogateKey);
GO

데이터 액세스 패턴

다음 섹션에서는 채워진 스키마에 대한 순위표 관련 액세스 패턴을 자세히 설명합니다.

순위 지정 작업

다음은 최고 점수 및 완료 레벨에 따라 하루 모든 플레이어 및 플랫폼 순위를 생성하는 예입니다. 결과는 LeaderboardSnapshot 테이블에 채워집니다. (앞서 언급한 16억 행 기록을 포함하는 참조 서비스 계층에서 이 쿼리는 대부분의 작업에서 Columnstore 인덱스 및 일괄 처리 모드 실행을 활용해 ~20초가 걸립니다.)

;WITH CTE_Leaderboard
AS (SELECT DENSE_RANK() OVER (ORDER BY GameCompletionScore DESC, GameCompletionLevel DESC) AS RankResult,
           PlayerSurrogateKey,
           GamePlatformSurrogateKey,
           GameCompletionLevel,
           GameCompletionScore,
           GameCompletionDate
    FROM dbo.GameCompletion
    WHERE CAST(GameCompletionDate AS DATE) = '2/26/2019')
INSERT dbo.LeaderboardSnapshot
(
    PlayerSurrogateKey,
    GamePlatformSurrogateKey,
    LeaderboardSnapshotDate,
    GameCompletionLevel,
    GameCompletionScore,
    GameCompletionDate,
    RankResultTypeSurrogateKey,
    RankResult
)
SELECT DISTINCT
       CTE_Leaderboard.PlayerSurrogateKey,
       CTE_Leaderboard.GamePlatformSurrogateKey,
       SYSDATETIME() AS LeaderboardSnapshotDate,
       GameCompletionLevel,
       GameCompletionScore,
       GameCompletionDate,
       2 AS RankResultTypeSurrogateKey, -- Day 
       CTE_Leaderboard.RankResult
FROM CTE_Leaderboard
ORDER BY RankResult;
GO

이전 작업에서 순위표 테이블에 순위 행을 삽입했습니다. 특정 날짜 및 순위 유형에 대해 이러한 결과를 검색하려면 다음 쿼리를 사용할 수 있습니다.

SELECT PlayerSurrogateKey,
       GamePlatformSurrogateKey,
       LeaderboardSnapshotDate,
       GameCompletionLevel,
       GameCompletionScore,
       GameCompletionDate,
       RankResultTypeSurrogateKey,
       RankResult
FROM dbo.LeaderboardSnapshot
WHERE LeaderboardSnapshotDate = '2019-02-28 18:08:01.0052490' 
    AND RankResultTypeSurrogateKey = 2
ORDER BY RankResult;
GO

LeaderboardSnapshot 테이블에서 추가 비클러스터형 인덱스를 만들어 일반적인 순위표 결과 쿼리 패턴(일반적인 조건자 및 조인 조건을 기반으로)을 지원하는 것이 좋습니다. 이전 쿼리 예제에서 다음 인덱스는 WHERE 절 조건자에서 참조된 두 열을 모두 포괄하므로 성능에 도움이 됩니다.

읽기 성능과 쓰기 오버헤드 간 상반 관계를 고려합니다. 추가 인덱스는 읽기 성능을 향상시킬 수 있지만 저장소 및 쓰기 오버헤드를 늘릴 수도 있습니다.

CREATE NONCLUSTERED INDEX [LeaderboardSnapshot_LeaderboardSnapshotDate_RankResultTypeSurrogateKey]
ON [dbo].[LeaderboardSnapshot] ([LeaderboardSnapshotDate],[RankResultTypeSurrogateKey])
INCLUDE ([GameCompletionLevel],[GameCompletionScore],[RankResult])
WITH (DATA_COMPRESSION = PAGE);
GO

결과를 페이징하는 실시간 순위 지정

특정 값 범위(예: 페이징 결과)에만 순위표 스냅샷이 필요한 경우에는 오프셋 행을 사용하여 T-SQL의 OFFSET ROWS FETCH NEXT 기능을 사용할 수 있습니다. 예를 들어 다음은 3월 10일자 GameCompletion의 모든 행에 대한 상위 100개 순위입니다(앞서 언급한 서비스 계층 및 테이블 크기에서 실행 시간 ~20초).

;WITH CTE_Leaderboard
AS (SELECT DENSE_RANK() OVER (ORDER BY GameCompletionScore DESC, GameCompletionLevel DESC) AS RankResult,
           PlayerSurrogateKey,
           GamePlatformSurrogateKey,
           GameCompletionLevel,
           GameCompletionScore,
           GameCompletionDate
    FROM dbo.GameCompletion
    WHERE CAST(GameCompletionDate AS DATE) = '3/10/2019')
INSERT dbo.LeaderboardSnapshot
(
    PlayerSurrogateKey,
    GamePlatformSurrogateKey,
    LeaderboardSnapshotDate,
    GameCompletionLevel,
    GameCompletionScore,
    GameCompletionDate,
    RankResultTypeSurrogateKey,
    RankResult
)
SELECT DISTINCT
       CTE_Leaderboard.PlayerSurrogateKey,
       CTE_Leaderboard.GamePlatformSurrogateKey,
       SYSDATETIME() AS LeaderboardSnapshotDate,
       GameCompletionLevel,
       GameCompletionScore,
       GameCompletionDate,
       2 AS RankResultTypeSurrogateKey, -- Day
       CTE_Leaderboard.RankResult
FROM CTE_Leaderboard
ORDER BY RankResult OFFSET 0 ROWS FETCH NEXT 100 ROWS ONLY;
GO

"내 주변" 순위 결과

다음 예제에서는 2019년 5월 1일부로 모든 플레이어에 대해 매일 순위를 생성했다고 가정합니다. 모든 플레이어의 결과가 LeaderboardSnapshot 테이블에 채워집니다.
이제 다음 조건 및 요구 사항을 고려합니다.

  • 플레이어 "242695"는 이 특정 순위 스냅숏에서 24,421위에 기록됩니다.
  • 이 플레이어는 바로 위와 아래로 10명의 플레이어를 보기를 원합니다.

순위가 이미 생성되어 LeaderboardSnapshot 테이블에 채워져 있으므로 다음 단계는 다음과 같은 쿼리를 실행하여 플레이어 "242695"의 주변 경쟁자 창을 생성하는 것입니다.

다음 예제에서는 게임 완료 날짜 및 순위 유형(CTE_NearMe)에 대한 공통 테이블 식, 플레이어 242695(CTE_PlayerRank)에 대한 위/아래 순위 경계를 정의하는 두 번째 일반 테이블 식, 그리고 이러한 CTE를 사용하여 가장 인접한 주변 순위 행을 가져오는 쿼리를 정의합니다.

;WITH CTE_NearMe
AS (SELECT PlayerSurrogateKey,
           GamePlatformSurrogateKey,
           LeaderboardSnapshotDate,
           GameCompletionLevel,
           GameCompletionScore,
           GameCompletionDate,
           RankResultTypeSurrogateKey,
           RankResult
    FROM dbo.LeaderboardSnapshot
    WHERE CAST(GameCompletionDate AS DATE) = '5/1/2019'
          AND RankResultTypeSurrogateKey = 2),
      CTE_PlayerRank
AS (SELECT (CTE_NearMe.RankResult - 10) AS LowerRankBound,
           (CTE_NearMe.RankResult + 10) AS UpperRankBound
    FROM CTE_NearMe
    WHERE CTE_NearMe.PlayerSurrogateKey = 242695)
SELECT CTE_NearMe.PlayerSurrogateKey,
       CTE_NearMe.GamePlatformSurrogateKey,
       CTE_NearMe.GameCompletionLevel,
       CTE_NearMe.GameCompletionScore,
       CTE_NearMe.GameCompletionDate,
       CTE_NearMe.RankResultTypeSurrogateKey,
       CTE_NearMe.RankResult
FROM CTE_NearMe
WHERE RankResult
BETWEEN
(
    SELECT LowerRankBound FROM CTE_PlayerRank
) AND
(
    SELECT UpperRankBound FROM CTE_PlayerRank
)
ORDER BY RankResult;
GO

싱글톤 조회 처리

다시 한 번, GameCompletion 테이블에 대한 임시 활동을 최소로 유지합니다. 이 표를 (순위표 생성이 아니라) 실시간 개별 점수 검색에 사용하는 경우 예상 조회 값을 기반으로 비클러스터형 b-트리 인덱스를 추가하는 것이 좋습니다.

드문 경우이지만, 다음은 GameCompletion의 기본 Columnstore 인덱스를 사용하는 단일 게임 결과 조회 작업의 예입니다.

SELECT GameCompletionSurrogateKey,
       PlayerSurrogateKey,
       GamePlatformSurrogateKey,
       GameCompletionLevel,
       GameCompletionScore,
       GameCompletionDate
FROM dbo.GameCompletion
WHERE PlayerSurrogateKey = 944799
    AND GameCompletionDate = '2019-12-30 00:00:02.9428411';
GO

비클러스터형 인덱스가 없는 경우에도 이 예제 싱글톤 조회 쿼리는 ~200밀리초밖에 걸리지 않습니다. 전체 쓰기 대기 시간 오버헤드와 저장소 공간에 대해 추가 인덱스의 이점을 측정합니다.

데이터 에이징

이 참조 아키텍처는 간편하게 오래된 데이터를 기록 테이블로 보관하고 마이그레이션하기 위한 것입니다. 다음 쿼리는 GameCompletionHistory에 데이터를 에이징하는 방법을 보여줍니다.

-- Switching out the oldest data by month
-- Partition “1” in this example is January 2019 data
ALTER TABLE dbo.GameCompletion 
    SWITCH PARTITION 1 
        TO dbo.GameCompletionHistory PARTITION 1;
GO

변경 및 아카이브 프로세스는 이 참조 아키텍처에서 설명한 모든 단계를 따른 것으로 간주하여 즉시(1초 미만) 실행됩니다. 보관된 데이터는 GameCompletionHistory에서 즉시 사용할 수 있습니다.

추가 리소스 및 샘플

가격

Azure 구독이 없는 경우 무료 계정을 만들어 12개월 무료 서비스를 시작합니다. 이러한 서비스의 제한을 초과하지 않는 한 Azure 무료 계정에서 무료로 제공하는 서비스에 대해서는 요금이 부과되지 않습니다. Azure Portal을 통해 또는 사용량 파일을 통해 사용량을 확인하는 방법을 알아보세요.

이러한 참조 아키텍처를 실행하는 동안 사용되는 Azure 서비스의 비용은 사용자가 부담합니다. 전체 금액은 사용량에 따라 달라집니다. 참조 아키텍처에 사용된 각 서비스에 대한 가격 웹 페이지를 참조하세요.

Azure 가격 계산기를 사용하여 사용하려는 Azure 서비스에 대한 비용을 구성하고 예측할 수도 있습니다. 가격은 추정치이며 실제 가격 견적이 아닙니다. 실제 가격은 구매 날짜, 결제 통화, 사용자가 Microsoft와 체결하는 계약 유형에 따라 다를 수 있습니다. 가격에 대한 추가 정보는 Microsoft 영업 담당자에게 문의하세요.