MySQL을 사용하여 구축한 데이터베이스가 있다면, 그 데이터베이스(및 애플리케이션)를 Couchbase로 옮길 수 있는지, 그리고 더 중요한 것은 어떻게 옮길 수 있는지 궁금할 것입니다. 가장 큰 걸림돌은 Couchbase를 만들거나 정보를 저장하는 기술적 측면이 아니라(물론 중요하지만), 데이터를 다른 방식으로 보고 애플리케이션의 작동 방식을 어떻게 바꾸는지 파악하는 것입니다.

먼저 MySQL 데이터베이스 구조를 Couchbase Server로 전환하는 방법과 Couchbase Server에서 데이터베이스를 쿼리하는 방법이 MySQL에서 사용되는 방법과 어떻게 다른지 살펴보겠습니다.

데이터 구조에 대해 먼저 생각하세요.

MySQL(및 기타 SQL 및 테이블 기반 데이터베이스)은 데이터를 테이블의 관점에서 생각하도록 강요합니다. 모든 데이터는 테이블이며, 복잡한 구조를 저장할 때는 개별 데이터가 하나 이상의 테이블로 분할될 수 있습니다. 일부 애플리케이션과 데이터 유형의 경우 이는 데이터에 접근하고 저장하는 데 있어 완벽하게 논리적이고 합리적인 방법입니다. 하지만 일부 애플리케이션의 경우 테이블 구조가 저장하려는 데이터에 잘 매핑되지 않는 경우가 있습니다.

일반적인 예로 레시피 데이터베이스를 살펴보겠습니다. 이것은 제가 잘 아는 분야입니다. Cheffy.com 는 MySQL 위에 구축되었습니다. 기본 테이블 구조는 레시피라는 핵심 테이블로, 레시피 이름, 부제목, 설명 및 제공 인원이 포함되어 있습니다. 재료 목록, 방법 단계, 메타데이터, 키워드 등 레시피에 대한 기타 관련 정보는 고유한 레시피 ID로 원본 레시피에 연결된 다른 테이블에 저장됩니다. 아래 그림에서 이를 아주 기본적으로 확인할 수 있습니다.

???

이 구조에는 몇 가지 잠재적인 이점이 있습니다. 예를 들어 특정 작업은 매우 간단하고 쉬울 수 있습니다. 예를 들어 '당근'이라는 재료가 들어간 모든 레시피를 찾고 싶으신가요? 재료 테이블에서 '당근'을 찾는 쿼리를 수행하여 일치하는 레시피 목록을 가져올 수 있습니다. 조인을 사용하면 재료 테이블에서 검색하여 재료 테이블의 레시피 ID를 레시피 제목의 레시피 ID에 연결하는 조인을 사용하여 레시피 테이블에서 레시피 목록, 제목 및 기타 정보를 얻을 수 있습니다.

???

이러한 종류의 검색은 쉽지만, 예를 들어 사용자에게 레시피를 표시하려는 경우와 같이 레시피에 대한 모든 정보를 수집하는 것은 매우 복잡할 수 있습니다. 단일 쿼리로 수행할 수도 있지만, 때로는 레시피 데이터를 가져오는 쿼리, 재료에 대한 쿼리, 메타데이터에 대한 쿼리 등 여러 개의 쿼리를 사용하는 것이 더 쉬울 수 있습니다. 애플리케이션 계층 내에서 이 작업은 자동으로 수행되어 객체를 구축한 다음 사용자에게 레시피를 형식에 맞게 표시하기 위한 기초로 사용됩니다.

많은 사용자와 애플리케이션의 경우, 이를 위해 특수 레이어를 구축하거나 여러 객체 관계형 매핑 시스템 중 하나를 사용하여 기본 테이블 구조의 데이터를 애플리케이션(및 사용자)이 익숙한 최상위 객체로 매핑합니다. 여기서는 레시피를 예로 들었지만 인보이스(송장, 공급업체, 목적지, 송장 라인) 및 블로그 게시물(게시물 콘텐츠, 키워드, 작성자, 댓글) 등 다양한 애플리케이션으로 확장할 수 있습니다.

이러한 테이블 기반 솔루션이 본질적으로 나쁜 것은 아니지만, 이러한 유형의 상황에서는 주요 정보가 여러 테이블에 저장되므로 여러 테이블을 서로 동기화 상태로 유지해야 합니다. 예를 들어 레코드가 삭제되면 어떻게 될까요? 원본에 연결되었을 수 있는 다른 모든 레코드를 수동으로 또는 계단식 삭제를 사용하여 삭제해야 합니다.) 마찬가지로 레시피에 대한 정보를 불러올 때는 5~10개의 정보 쿼리를 함께 실행하게 됩니다.

Couchbase는 다른 접근 방식을 취합니다. 서로 다른 정보를 저장할 수 있는 여러 개의 테이블 대신, Couchbase에서는 단일 구조(JavaScript 객체 표기법 JSON) 형식을 저장합니다. JSON 형식은 필드, 배열, 객체 및 스칼라 유형의 복잡한 구조를 허용하며, 이를 전체 레코드로 결합할 수 있습니다. 즉, 이제 기존의 여러 테이블로 구성된 엔티티(레시피, 블로그 게시물)를 하나의 '문서'로 표현할 수 있습니다.

{
"title" : "당근과 고수 수프"
"서빙" : 4,
"subtitle" : "통밀 빵으로 맛있게",
"PREPTIME" : 8,
"cooktime" : 12,
"총시간" : 20,
"ingredients" : [
{
"금액" : 250,
"성분" : "당근",
"측정" : "G"
},
{
"금액" : 75,
"성분" : "고수",
"측정" : "G"
},
{
"금액" : 250,
"성분" : "야채 육수",
"측정" : "ml"
}
],
"method" : [
"당근 자르기",
"모든 재료를 팬에 조리",
"유동화"
}
],
}

이제 레시피와 관련된 모든 것이 한곳에 있으며, Couchbase 데이터베이스에서 한 번의 작업으로 레시피를 로드할 수 있습니다.

콘텐츠에 대한 구조나 정의는 없으며, Couchbase 데이터베이스의 모든 문서에는 어떤 구조든 포함할 수 있습니다. 하지만 데이터베이스에 제공된 문서의 구조가 올바른지 확인하는 유효성 검사 루틴을 적용할 수 있습니다. 유효성 검사는 필드와 그 내용을 모두 포함할 수 있습니다.

또한 엄격한 구조가 없기 때문에 정보를 저장하는 대상과 방법에 추가적인 유연성이 있다는 점도 염두에 두세요. 레시피 문서에 레시피를 제공한 사람에 대한 데이터를 데이터베이스에 보관하는 새 섹션을 추가하는 것은 문서 구조를 확장하는 경우입니다.

다중 테이블이라는 개념도 없습니다. 데이터베이스와 그 데이터베이스에 포함된 문서만 있을 뿐입니다. 동일한 데이터베이스 내에서 다양한 유형의 정보를 지원하려면 문서에 필드를 추가하면 됩니다. 예를 들어 레시피를 식별할 수 있습니다:

{
"유형" : "레시피",
"title" : "당근과 고수 수프"
"서빙" : 4,
"subtitle" : "통밀 빵으로 맛있게",

}

레코드 유형의 식별은 데이터베이스 시스템의 다른 영역에서 로드 중인 데이터를 인식(및 선택)하는 데 도움이 될 수 있습니다.

모든 것이 문서인 경우 기록 목록을 얻으려면 어떻게 해야 하나요?

첫 번째 섹션에서는 MySQL을 사용하여 당근이 포함된 레시피 목록을 가져오는 간단한 SQL 문을 작성하는 방법에 대해 설명했습니다. MySQL에서는 재료 테이블에서 값을 검색하여 레시피 ID를 찾은 다음 조인을 사용하여 레시피 테이블에서 레시피 제목을 가져오는 방식으로 작동합니다. 속도 향상을 위해 일반적으로 쿼리의 응답 시간을 개선하기 위해 인덱스를 사용하여 각 레코드를 개별적으로 살펴보는 데 시간을 절약할 수 있습니다.

카우치베이스에서는 모든 것이 문서이며, 필드도 없고 테이블도 없기 때문에 테이블의 필드를 검색하는 내장된 메서드가 없습니다. 엄격한 구조가 없기 때문에(그리고 데이터베이스 엔진이 자유 형식 문서의 필드를 식별할 방법이 없기 때문에) 일반적으로 목록(또는 테이블)에서 작동하는 모든 작업을 어떻게 수행할 수 있을까요? 간단한 '모든 레시피 나열하기'부터 '당근이 재료인 모든 레시피 찾기'까지 모든 작업은 어딘가에서 목록을 사용해야 합니다.

카우치베이스는 뷰라는 구성을 지원합니다. 뷰는 원칙적으로 MySQL의 뷰와 유사하지만, Couchbase에서는 뷰가 데이터베이스에서 문서 목록을 가져오는 유일한 방법이지 대체 .

뷰는 실제로 세 가지를 정의합니다:

  • 뷰에 포함된 정보의 구조입니다. MySQL 내에서 테이블을 정의하는 것처럼 테이블의 구조를 정의하는 것으로 생각할 수 있습니다.
  • 검색할 수 있는 필드 또는 정보입니다. 뷰는 키와 값이라는 두 가지 요소를 출력합니다. 키는 원하는 데이터베이스 콘텐츠를 검색하거나 더 구체적으로 말하면 선택할 수 있는 방법을 구성합니다.
  • 구조 및 키에 대한 인덱스입니다. 인덱스는 뷰에 보고된 데이터의 검색을 개선하는 데 사용됩니다.

뷰는 디자인 문서 내에서 자바스크립트로 문서를 받아들이는 함수를 사용하여 정의됩니다. 뷰가 구성되면 데이터베이스의 모든 문서가 뷰에 제공되고 뷰는 출력에 표시하려는 정보를 내보냅니다. 자바스크립트는 클라이언트가 아닌 서버에서 실행되므로 걱정하지 마세요.

따라서 잠시 MySQL로 돌아가서, WHERE 절이 없는 쿼리를 작성하고, 쿼리 출력을 반환할 필드를 선택하고, 출력에 일치하는 행의 목록을 구성합니다. 이제 SQL 문을 살펴보겠습니다:

MySQL에서 쿼리를 실행할 때 MySQL 서버는 테이블의 정보를 가져온 다음 다음과 같이 반환할 레코드 목록(및 해당 필드)을 구성합니다:

Couchbase에서 뷰는 개별 문서 정보로부터 레코드 목록을 구성하고, 그 과정의 부작용으로 인덱스를 생성합니다. 그 결과 뷰에서 생성된 모든 문서의 목록이 생성됩니다.

???

MySQL에서는 WHERE 절로 쿼리를 실행할 때 인덱스(희망사항)를 사용하여 선택하려는 레코드를 선택하는 데 도움을 줍니다:

???

CouchBase에서 생성된 뷰는 테이블이며, 뷰를 쿼리할 때 CouchBase는 키 값(및 생성된 연관 인덱스)을 사용하며, 사용자가 지정한 쿼리 값으로 반환된 정보를 필터링하여 일치하는 레코드의 최종 목록을 생성합니다.

쿼리할 테이블을 지정하는 이 방법을 사용하면 데이터베이스에서 정보를 추출하는 방식을 단순화하고 최적화할 수 있습니다. 하지만 정보를 쿼리하는 방법에 대해 좀 더 고민해야 한다는 의미이기도 합니다.

다음 시간

이제 MySQL이 정보를 저장하고 쿼리하는 방법과 이러한 지식을 Couchbase Server 2.0으로 정보를 마이그레이션할 때 어떻게 변환할 수 있는지 알게 되었습니다. 다음 시간에는 배운 내용을 바탕으로 몇 가지 쿼리를 작성하고 고급 쿼리와 마이그레이션 프로세스에 대해 살펴보겠습니다.