카우치베이스 서버

SQL과 NoSQL 비교: ASP.NET 애플리케이션

이 SQL과 NoSQL 비교는 SQL Server 데이터베이스를 Couchbase로 변환한 후 다음 단계입니다. In 이전 게시물를 사용하여 SQL Server에서 Couchbase로 AdventureWorks를 복사했습니다.

이 글에서는 SQL Server를 사용하는 ASP.NET Core 애플리케이션과 동일한 애플리케이션이 Couchbase를 사용하는 방법을 보여드리겠습니다. 따라 해보고 싶으시다면 SqlServerToCouchbase 프로젝트 에서 확인하세요.

이전 게시물과 달리 애플리케이션의 "자동" 변환을 시도하지 않습니다. 대신 애플리케이션 수준에서 SQL과 NoSQL을 비교하는 것으로 생각하시면 됩니다.

ASP.NET SQL Server 애플리케이션

아주 간단한 ASP.NET Core REST API 스타일의 애플리케이션을 만들었습니다. 저는 엔티티 프레임워크를 사용했지만 Dapper, ADO.NET, NHibernate 등을 사용하시는 분들도 쉽게 따라할 수 있을 것입니다.

각 엔드포인트는 JSON을 반환합니다. 또한 프로젝트에 Swashbuckle을 추가하여 브라우저에서 OpenAPI를 통해 바로 요청을 발행할 수 있도록 했습니다.

ASP.NET 카우치베이스 서버 애플리케이션

카우치베이스 버전의 애플리케이션은 동일한 SQL Server AdventureWorks 데이터를 사용하기 때문에 동일한 데이터를 반환합니다.

애플리케이션에서 저는 카우치베이스 .NET SDK 그리고 카우치베이스 거래 라이브러리. (다음을 사용할 수 있습니다. Linq2Couchbase 엔티티 프레임워크 대체의 한 유형으로).

그렇지 않으면 애플리케이션은 동일하며 SQL과 NoSQL 비교(및 대조)를 제공합니다. 엔드포인트는 JSON을 반환하고 Swashbuckle이 설치되어 있습니다.

각 샘플에는 컨트롤러가 하나씩 있습니다. 컨트롤러의 각 엔드포인트를 살펴보고 SQL과 NoSQL 비교를 수행해 보겠습니다.

SQL과 NoSQL 비교: ID로 가져오기

먼저 GetPersonByIdAsync 엔드포인트입니다. 개인 ID가 주어지면 이 엔드포인트는 주어진 ID에 대한 개인 데이터를 반환합니다.

SQL Server

다음은 엔티티 프레임워크를 사용하는 SQL Server 예제입니다:

이 메서드의 다른 버전도 작성했습니다. GetPersonByIdRawAsync 는 "원시" SQL 쿼리를 사용합니다. 이 쿼리는 엔티티 프레임워크(위)가 궁극적으로 생성하는 쿼리와 매우 유사하며, Dapper 접근 방식과도 유사합니다.

어느 쪽이든 SQL 쿼리가 실행되고 있다는 점에 유의하세요.

N1QL을 사용하면 매우 유사한 방식으로 Couchbase의 데이터를 쿼리할 수 있습니다. 다음은 GetPersonByIdRawAsync 를 사용하세요:

("버킷"에서 "클러스터"로 이동하는 추가 단계가 있습니다. 이 단계를 건너뛸 수도 있지만 저는 컨트롤러의 다른 곳에서 버킷을 사용하기 때문에 그대로 두었습니다.)

그러나 N1QL 쿼리를 사용하면 인덱싱, 쿼리 구문 분석 등 약간의 추가 오버헤드가 발생합니다. Couchbase를 사용하면 이미 개인 ID를 알고 있는 경우 N1QL 쿼리를 건너뛰고 직접 키/값(K/V) 조회를 수행할 수 있습니다.

K/V로 신분증 확인

키는 이미 알고 있으므로 인자로 주어집니다. SQL을 사용하는 대신 키/값 조회를 해보겠습니다. 저는 다음과 같은 엔드포인트 메서드에서 이 작업을 수행했습니다. GetPersonByIdAsync:

SQL Server와 달리 Couchbase는 데이터와 상호 작용할 수 있는 다양한 API를 지원합니다. 이 경우 키/값 조회는 메모리에서 직접 Person 문서를 가져옵니다. SQL 쿼리를 파싱하거나 인덱싱을 사용할 필요가 없습니다. Couchbase의 키/값 조회는 종종 마이크로초 단위로 측정됩니다.

제 조언: 가능하면 키/값 조회를 사용하세요.

ID로 확장된 엔터티 가져오기

데이터는 복잡하고 여러 테이블에 걸쳐 있을 수 있습니다(또는 Couchbase의 경우 여러 문서에 걸쳐 있을 수 있습니다). 사용 중인 도구에 따라 관련 엔티티를 로드할 수 있는 일부 기능이 있을 수 있습니다.

예를 들어, 엔티티 프레임워크를 사용하면 포함 를 사용하여 다음과 같이 관련 엔티티를 가져옵니다. GetPersonByIdExpandedAsync 예제:

엔티티 프레임워크는 이 작업을 수행하기 위해 뒤에서 JOIN 및/또는 여러 SELECT 쿼리를 생성할 수 있습니다.

엔티티 프레임워크뿐만 아니라 모든 O/RM이 위험할 수 있는 부분입니다. SQL 프로파일러와 같은 도구를 사용하여 실제로 어떤 쿼리가 실행되고 있는지 확인해야 합니다.

참고
O/RM이 도움이 될 수 있지만 SQL에서 NoSQL로 와 비교할 때, 임피던스 불일치는 NoSQL 세계에서 훨씬 덜 문제가 된다는 점을 기억하는 것이 중요합니다.

Couchbase 샘플의 경우, 엔티티 프레임워크를 사용하지 않고 대신에 NEST 구문 SQL 표준의 N1QL 확장의 일부입니다. 다음은 Couchbase 버전의 GetPersonByIdExpandedAsync 외모:

NEST는 조인된 데이터를 중첩된 JSON 객체에 넣는 일종의 JOIN입니다. O/RM을 사용하여 데이터를 매핑하는 대신 이 데이터를 C# 객체로 직접 직렬화할 수 있습니다.

페이징 쿼리

데이터를 조회할 수 있는 키가 하나도 없는 경우를 예로 들어보겠습니다. 결과의 '페이지'를 반환하는 메서드를 살펴보겠습니다(아마도 UI 그리드나 목록을 채우기 위한 것일 수 있습니다).

SQL Server의 페이징

SQL Server 버전은 다음과 같습니다. GetPersonsPageAsync:

엔티티 프레임워크 사용, 주문 기준, 건너뛰기Take 는 일반적으로 페이징에 사용됩니다. SQL Server 프로파일러를 열면 생성되는 SQL은 다음과 같습니다:

오프셋 ... 행 가져 오기 다음 ... 는 여기서 페이징에 사용되는 구문입니다.

Couchbase의 페이징

페이징 구문은 항상 SQL 구현에 따라 다릅니다. Couchbase는 이 점에서 Oracle/MySQL 구문에 더 의존합니다. 다음은 Couchbase 버전의 GetPersonsPageAsync:

이 경우 제한 ... 오프셋 ... 가 사용 중입니다.

또한 p.LastName이 누락되지 않은 경우. 카우치베이스는 NoSQL 데이터베이스이므로 쿼리 엔진은 다음을 가정할 수 없습니다. 를 포함한 모든 문서에 p.성으로 주문. 이것을 추가하면 어디 절을 사용하면 쿼리는 이제 어떤 인덱스를 사용할지 알 수 있습니다. 이 절이 없으면 쿼리를 실행하는 데 훨씬 더 오래 걸립니다.

ACID 트랜잭션으로 업데이트

이 예제에서는 SQL Server와 Couchbase 모두에서 관계형 모델을 사용하므로 두 애플리케이션 모두에서 ACID 트랜잭션이 중요할 것입니다.

이 예제에서는 PersonUpdateApi 를 업데이트할 수 있습니다. 둘 다 사람의 이름과 이메일 주소입니다. 이 데이터는 두 개의 개별 테이블/행(SQL Server) 또는 두 개의 개별 문서(Couchbase)에 있으므로, 이 작업은 전부 아니면 전무의 원자 연산이 되기를 원합니다.

참고
한 사람이 여러 개의 이메일 주소를 가질 수 있지만 이 데이터 세트에서는 드물기 때문에 (API를 단순화하기 위해) 둘 다에 대해 ID를 지정합니다.

엔티티 프레임워크가 포함된 ACID

다음은 엔티티 프레임워크를 사용하여 Person 테이블의 데이터 행과 EmailAddress 테이블의 데이터 행을 모두 업데이트하는 ACID 트랜잭션의 예입니다.

거래의 네 가지 주요 부분에 유의하세요:

  1. 거래 시작(_context.Database.BeginTransactionAsync();)
  2. 시도/catch
  3. 트랜잭션 커밋(트랜잭션.CommitAsync()를 기다립니다;)
  4. 롤백 트랜잭션의 catch (트랜잭션.롤백비동기();)

이것은 최근 몇 년 동안 SQL과 NoSQL을 비교하는 중요한 기능입니다. Couchbase를 사용하면 이제 ACID 트랜잭션이 가능합니다.

카우치베이스 트랜잭션이 있는 ACID

카우치베이스의 경우 API는 약간 다르지만 단계는 모두 동일합니다:

주요 단계는 동일합니다:

  1. 거래 시작(트랜잭션.RunAsync( ... ))
  2. 시도/catch
  3. 트랜잭션 커밋(암시적이지만 context.CommitAsync() 사용 가능)
  4. 롤백 트랜잭션(다시 한 번 암시되지만 context.RollbackAsync() 를 사용할 수 있습니다).

두 경우 모두 ACID 트랜잭션이 있습니다. 와 달리 그러나 SQL Server는 나중에 Couchbase의 데이터를 최적화하고 통합하여 필요한 ACID 트랜잭션의 양을 줄이고 성능을 향상시킵니다.

저장 프로시저: SQL과 NoSQL 비교

저장 프로시저는 때때로 논란의 여지가 있는 주제입니다. 일반적으로 저장 프로시저에는 많은 기능과 논리가 포함될 수 있습니다.

SQL Server의 저장 프로시저

"ListSubcomponents"라는 저장 프로시저를 만들었습니다 ( 깃허브에 대한 자세한 내용). 엔티티 프레임워크에서는 다음을 사용할 수 있습니다. FromSqlRaw 를 실행하고 그 결과를 C# 객체에 매핑합니다. 의사 엔티티 C# 객체를 다음과 같이 만들었습니다. 하위 컴포넌트 나열 이 스프로크에만 사용됩니다:

저장 프로시저에는 두 개의 매개 변수가 있습니다.

카우치베이스 사용자 정의 기능

Couchbase에는 아직 "저장 프로시저"라는 것이 없지만, 필요한 경우 복잡한 로직을 포함할 수 있는 사용자 정의 함수(UDF)라는 것이 있습니다.

라는 UDF를 만들었습니다. 하위 컴포넌트 나열 (또한 깃허브에서 보기)의 기능과 일치하는 SQL Server 스프로크입니다.

ASP.NET에서 해당 UDF를 실행하는 방법은 다음과 같습니다:

두 개의 매개 변수를 사용하여 Couchbase에서 이를 호출하는 것은 엔티티 프레임워크에서 FromSqlRaw를 사용하는 것과 매우 유사합니다.

성능 - SQL과 NoSQL 비교

이제 앱을 Couchbase를 사용하도록 변환했는데 새 버전이 적어도 이전 SQL Server 버전만큼 빠르게 실행되나요?

대답하기 복잡한 질문입니다:

  • 데이터 모델을 최적화하지 않았습니다. 여전히 다음에서 데이터를 리터럴로 변환하는 방식을 사용하고 있습니다. 이전 게시물.
  • 데이터 액세스는 사용 사례마다 매우 다양할 수 있습니다.
  • 환경은 사람마다, 회사마다 크게 다를 수 있습니다.

하지만 저는 정신 상태를 점검하기 위해 '백 오브 더 엔벨로프' 부하 테스트를 해보고 싶었습니다.

로컬 컴퓨터에서 두 애플리케이션을 모두 실행했고, 다음을 사용했습니다. ngrok 를 사용하여 인터넷에 노출시켰습니다. 그런 다음 loader.io (동시성 부하 테스트를 위한 훌륭한 도구). 그런 다음 '페이징' 엔드포인트에 대해서만 몇 가지 간단한 성능 테스트를 실행했습니다. 이 엔드포인트는 제가 성능에 대해 가장 우려하는 엔드포인트이며, 엔드포인트 중에서 가장 "사과와 사과"를 비교한 SQL 및 NoSQL이라고 생각합니다.

로드 테스트 SQL과 NoSQL 비교

다음은 SQL Server 애플리케이션의 결과입니다:

SQL and NoSQL comparison - SQL Server load testing

다음은 카우치베이스 서버 애플리케이션의 결과입니다:

SQL and NoSQL comparison - Couchbase Server load testing

SQL 및 NoSQL 비교 부하 테스트 결과 해석하기

이것은 "Couchbase가 SQL Server보다 빠르다"는 벤치마크나 데이터 포인트가 아닙니다.

이는 단지 정신 상태를 점검하기 위한 것입니다.

부하가 걸린 상태에서 이전만큼 좋은 성능을 얻지 못한다면 뭔가 잘못하고 있는 것일 수 있습니다. 이는 개념 증명 프로세스. 카우치베이스, 특히 카우치베이스 7은 매우 관계형 친화적이지만, 여전히 다음과 같은 차이점과 뉘앙스가 있습니다. 모든 이 프로세스를 통해 여러분과 프로젝트에 가장 중요한 차이점을 파악할 수 있습니다.

보다 강력한 벤치마크를 찾고 계신다면 다음 리소스를 참고하세요:

결론

아주 기본적인 부하 테스트와 함께 애플리케이션 코드의 SQL과 NoSQL 비교 및 변환을 통해 제가 할 수 있다는 것을 알 수 있었습니다:

  • 모델링 변경 없이 관계형 데이터 모델 그대로 호스팅
  • Couchbase SDK를 사용하도록 ASP.NET 엔드포인트 변환하기
  • 낮은 위험으로 확장 및 개선할 수 있는 충분한 여지가 있는 최소한의 성능으로 시작할 수 있을 것으로 기대합니다.

사용 사례는 다를 수 있지만, 이 전환 과정에서 Couchbase가 제공한 정보를 기억하세요:

부록

다음은 제가 애플리케이션에서 수행한 SQL과 NoSQL 비교에 대한 간결한 가이드입니다.

SQL Server 작업 카우치베이스 운영

한 행/엔터티 읽기/쓰기

키/값 조회

여러 행/페이지 읽기/쓰기

N1QL 쿼리

관련 엔티티가 있는 엔티티 하나를 선택합니다.

N1QL 쿼리 NEST

BeginTransaction

Transaction.Create

저장 프로시저

UDF (이벤트 를 사용하는 것도 유용할 수 있습니다)

미리 알림:

  1. 가능하면 키/값 API로 전환하세요.
  2. N1QL 작성 시 인덱싱, 인덱싱 계획 시각화 및 인덱스 어드바이저 사용
  3. 다음과 같은 경우에만 ACID 트랜잭션을 사용합니다.
  4. 성능 목표에 대해 생각하고 테스트 방법을 설정하세요.

다음 단계

확인 현재 베타 버전인 Couchbase Server 7를 지금 다운로드하세요. 무료로 다운로드할 수 있습니다. 관계형 데이터를 로드하고 몇 가지 엔드포인트를 변환하여 프로세스가 제대로 작동하는지 확인해 보세요.

이 문서 공유하기
받은 편지함에서 카우치베이스 블로그 업데이트 받기
이 필드는 필수 입력 사항입니다.

작성자

게시자 매튜 그로브스

Matthew D. Groves는 코딩을 좋아하는 사람입니다. C#, jQuery, PHP 등 무엇이든 풀 리퀘스트를 제출할 정도로 코딩을 좋아합니다. 90년대에 부모님의 피자 가게를 위해 QuickBASIC POS 앱을 만든 이후로 전문적으로 코딩을 해왔습니다. 현재 Couchbase의 선임 제품 마케팅 관리자로 일하고 있습니다. 여가 시간에는 가족과 함께 축구 경기를 관람하고 개발자 커뮤니티에 참여하며 시간을 보냅니다. 그는 .NET의 AOP, .NET의 프로 마이크로서비스, Pluralsight 저자, Microsoft MVP의 저자이기도 합니다.

댓글 남기기

카우치베이스 카펠라를 시작할 준비가 되셨나요?

구축 시작

개발자 포털에서 NoSQL을 살펴보고, 리소스를 찾아보고, 튜토리얼을 시작하세요.

카펠라 무료 사용

클릭 몇 번으로 Couchbase를 직접 체험해 보세요. Capella DBaaS는 가장 쉽고 빠르게 시작할 수 있는 방법입니다.

연락하기

카우치베이스 제품에 대해 자세히 알고 싶으신가요? 저희가 도와드리겠습니다.