Computer >> 컴퓨터 >  >> 프로그램 작성 >> 데이터 베이스

이상한 커플:MongoDB와 MySQL

데이터 저장소를 선택하는 동안 사용할 수 있는 선택 항목과 조합은 더 이상 만능 데이터 저장소 세계가 아님을 증명합니다.

오늘날에는 SQL 데이터 저장소(예:MySQL, PostgreSQL, Oracle 또는 SQLServer)를 NoSQL 데이터 저장소(MongoDB, CouchDB 및 Neo4J 등)와 혼합하고 일치시켜야 하는 강력한 이유가 있습니다. Oracle이 여전히 선호되는 기록 시스템일 수 있습니다. 기업, 더 이상 마을의 유일한 게임이 아닙니다.

개발자들은 문제를 해결하기 위해 SQL과 NoSQL의 조합을 사용하기 시작했습니다. 때로는 DBA나 IT 부서의 요구에 반하는 경우도 있습니다.

작업에 적합한 도구 선택

오늘날의 데이터 저장소에는 열 패밀리, 문서, 그래프, 키-값 및 관계형의 5가지 광범위한 범주가 있습니다. 다중 언어 지속성은 문자 그대로 데이터를 저장하거나 유지하기 위해 많은 언어를 사용하는 것을 의미합니다. 보다 실용적인 용어로 이것은 동일한 애플리케이션 내에서 데이터에 액세스하기 위해 Cypher, JSON, SQL 또는 기타 여러 쿼리 언어를 사용할 수 있음을 의미합니다. 이러한 다양한 데이터 저장소 및 개발자가 지속성 요구 사항에 대한 솔루션에서 레이저로 더 나은 도구를 찾음에 따라 서로 다른 언어가 더욱 두드러지고 있습니다.

Sadalage와 Fowler는 NoSQL Distilled에서 여러 언어로 된 지속성의 필요성을 다음과 같이 언급합니다.

<블록 인용>

서로 다른 데이터베이스는 서로 다른 문제를 해결하도록 설계되었습니다. 모든 요구 사항에 대해 단일 데이터베이스 엔진을 사용하면 일반적으로 솔루션이 성능이 저하됩니다. 거래 데이터 저장, 세션 정보 캐싱, 고객의 그래프 [원문 그대로] 이동 및 친구가 구매한 제품은 본질적으로 다른 문제입니다.

<블록 인용>

데이터 관계에 대해 생각해 봅시다. RDBMS 솔루션은 관계가 존재하도록 하는 데 능숙합니다. 관계를 검색하거나 동일한 개체에 속한 다른 테이블에서 데이터를 찾아야 하는 경우 RDBMS 사용이 어려워지기 시작합니다.

Datastore 선택은 다음 두 가지 기준에 따라 결정됩니다.

  1. 저장되는 데이터의 구조
  2. 데이터와 상호작용하는 데 사용되는 쿼리

데이터를 쿼리하는 방식은 데이터를 구조화하는 방식을 변경합니다. 위에서 Sadalage와 Fowler가 언급했듯이 관계형 데이터 저장소는 관련 엔터티를 적용하는 데 탁월합니다. 그러나 이러한 개체 간의 다른 관계를 발견해야 하는 즉시 방해가 됩니다.

아래에서는 MongoDB를 사용한 CraigsList 데이터 보관 사용 사례에 대해 논의하고 이 작업을 수행한 방법을 추측합니다.

플레이어:MongoDB, MySQL 및 CraigsList

몽고DB

MongoDB는 MySQL에 대한 선호되는 NoSQL 대안이 되었습니다. 그 많은 이점에는 확장성, 자동 샤딩 및 오늘날의 인기 있는 프로그래밍 언어에 대한 기본 바인딩 가용성이 포함됩니다. MongoDB와 관계형 데이터 저장소 간의 핵심 차별화 요소는 MongoDB가 데이터에 대해 생각하고 저장하는 방식입니다. 관계를 적용하기 위해 외래 키 제약 조건이 있는 테이블 모음을 사용하여 MongoDB의 데이터는 문서 모음으로 표시됩니다.

문서는 관계형 데이터 구조의 행 또는 튜플과 유사합니다(동일하지 않음). 문서 데이터 저장소의 분류 및 명명법은 컬렉션으로 그룹화된 JSON 문서로 저장되는 데이터에서 직접 가져옵니다. 이러한 문서의 깊이는 무제한이며 다음을 통해 완전히 검사할 수 있습니다. 쿼리 또는 인덱스. 일반적으로 MongoDB에 대한 데이터의 좋은 표현은 관계형 데이터베이스에 적합한 데이터를 비정규화하여 얻을 수 있습니다. 물론 만들고자 하는 특정 쿼리가 이 프로세스를 안내해야 합니다.

MongoDB의 뉘앙스에 대한 자세한 내용은 MongoDB 웹사이트에서 확인할 수 있습니다.

MySQL

모든 사람이 알고 사랑하는 고전인 MySQL은 (시간 계산 계산에서) 태초부터 존재했으며 가장 널리 사용되는 DBMS입니다. 제공하는 기능을 통해 애플리케이션은 거의 10년 동안 데이터를 모델링하고 시스템 역할을 할 수 있습니다. 많은 비즈니스 목적에 대한 기록입니다. 요즘 사람들은 관계형 데이터베이스를 생각할 때 아마도 MySQL을 생각할 것입니다.

MySQL은 우리에게 고전적인 관계형 데이터 모델의 구현을 제공합니다. 유형 이론과 집합 이론을 사용하여 E.F. Codd가 1970년대에 개발했습니다. 프로그래밍 방식으로 정규화, 계획 또는 내부 검사할 수 있기 때문에 관계형 데이터 시스템이 매우 유명해집니다.사실 , 이러한 데이터 저장소는 일반적인 방식으로 데이터 모델링 문제를 해결하기 때문에 계속 선호되고 있습니다.

CraigsList

MongoDB와 MySQL 데이터 저장소를 모두 사용하는 잘 알려진 온라인 비즈니스 중 하나는 CraigsList입니다. 두 데이터 저장소를 나란히 채택하는 방법은 MongoDB 사례 연구에 설명되어 있지만 아래는 미리보기 이미지입니다.

규제 요구 사항으로 인해 Craigslist는 해당 분류의 디지털 기록을 유지해야 합니다. 하루에 백만 개 이상의 새로운 분류가 있으므로 CraigsList가 유지해야 하는 상당한 양의 데이터입니다. MySQL 데이터 저장소를 사용하여 분류에 대한 모든 활성 정보를 보유하는 반면 MongoDB는 보관된 데이터를 저장하는 데 사용되며 30일 이상일 수 있습니다. 정상적인 비즈니스 변경의 일부로 저장된 데이터의 데이터 스키마가 변경됩니다. 보관된 데이터에 MongoDB를 사용하여 CraigsList는 데이터를 효과적으로 분할하고 다음으로 인한 문제를 완화할 수 있었습니다. 스키마 마이그레이션.

사고 실험으로 CraigsList와 유사한 애플리케이션에서 MongoDB와 MySQL을 나란히 사용하기 위한 한 가지 가능한 구현에 대해 추측하고 싶습니다. 이것이 CraigsList가 실제로 데이터 저장을 수행하는 방식일 가능성은 거의 없지만 흥미롭습니다. 친숙하고 트랜잭션이 많은 웹 사이트에서 여러 데이터 저장소가 함께 작동할 수 있는 방법을 살펴봅니다.

어떻게 이루어지나요?

개발자와 엔지니어는 부피가 큰 SQL 데이터베이스에서 스키마 업데이트를 수행할 때 필연적으로 문제에 부딪힙니다. 스키마 업데이트를 적용한 후 "수정"할 데이터가 줄어들면 이러한 문제를 피할 수 있습니다. 이러한 마이그레이션 또는 스키마 업데이트의 고통은 일반적으로 증가합니다. 데이터 양에 비례합니다.

이 예에서 CraigsList에 항목을 판매하는 사용자로부터 새로운 정보가 필요하다고 가정해 보겠습니다. 스키마를 업데이트해야 하기 때문에 CraigsList는 업데이트의 고통을 최소화하기 위해 영향을 받는 데이터의 크기를 줄이기를 원할 것입니다.

이러한 몇 번의 보관 및 마이그레이션 주기 후에 CraigsList는 단일 위치에 상주하는 경우 스키마 없는 데이터 저장소가 필요한 이기종 데이터의 방대한 컬렉션을 구축하게 될 것입니다. MongoDB는 이 법안에 매우 적합합니다.

분류에 대한 예제 스키마는 다음과 같습니다(craigslist-clone에서 뻔뻔스럽게 다시 구현됨).

CREATE TABLE `classifieds` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `title` varchar(75) COLLATE utf8_unicode_ci DEFAULT NULL,
  `description` text COLLATE utf8_unicode_ci,
  `location` varchar(75) COLLATE utf8_unicode_ci DEFAULT NULL,
  `adtype` varchar(1) COLLATE utf8_unicode_ci DEFAULT 'O',
  `email` varchar(75) COLLATE utf8_unicode_ci DEFAULT NULL,
  `phone` varchar(75) COLLATE utf8_unicode_ci DEFAULT NULL,
  `activation_code` varchar(40) COLLATE utf8_unicode_ci DEFAULT NULL,
  `status` tinyint(4) DEFAULT '0',
  `category_id` int(11) DEFAULT NULL,
  `subcategory_id` int(11) DEFAULT NULL,
  `city_id` int(11) DEFAULT NULL,
  `permalink` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
  `image_file_name` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
  `image_content_type` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
  `image_file_size` int(11) DEFAULT NULL,
  `created_at` datetime DEFAULT NULL,
  `updated_at` datetime DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

물론 CraigsList는 다른 스키마를 가질 가능성이 높으며 몇 번의 반복 후에 최소한 현재 스키마를 발견했습니다. 또한 데이터 구성 방식을 변경하고 향후 스키마를 다시 변경할 수도 있습니다. 우리는 created_atupdated_at MySQL에 포함된 데이터를 아카이브할 시기를 결정하는 필드입니다.

Craigslist의 분류 정책에 따라 웹사이트에서 분류된 항목을 2주 동안 계속 사용할 수 있다고 가정해 보겠습니다. 이 시간이 지나면 분류된 항목을 계속 사용할 수 있지만 (MySQL에서) 반드시 활성화되는 것은 아닙니다. 이를 수행하기 위해 SQLAlchemy의 조합을 사용할 수 있습니다. 및 파이몽고:

먼저 MySQL 인스턴스에서 데이터를 가져와야 합니다. 이를 수행하기 위해 SQLAlchemy를 사용하고 스키마를 검사하도록 할 것입니다(이 코드를 이 목적에 훨씬 더 많이 재사용할 수 있도록 함).

import sqlalchemy.schema

m = sqlalchemy.schema.MetaData("mysql://root:I'm required why?@192.0.2.3/craigslist")
m.reflect()

print m.tables.keys()

데이터베이스에 성공적으로 연결하면 표준 파이썬 방식으로 인쇄된 키(열 이름)를 볼 수 있습니다. [u'classifieds', u'cities', u'subcategories', u'categories'] .우리는 여전히 이 테이블에서 개별 데이터 항목을 가져와야 합니다. 볼 수 있을 뿐만 아니라 SQLAlchemy는 이를 훨씬 쉽게 만들어주는 우아한 인터페이스도 제공합니다.

이제 내부 검사에서 테이블 정의를 얻었습니다. 객체 맵을 생성하거나 테이블에 포함된 데이터 항목을 가져오기 위해 해당 테이블을 쿼리할 시간입니다. 아래 쿼리는 데이터 저장소에서 분류를 추출합니다(다른 테이블은 독자).

import sqlalchemy.sql

connection = m.bind.connect()

classifieds = m.tables['classifieds']

query = classifieds.select()

result = connection.execute(query)

for row in result:
    print dict(row.items())

이 스니펫은 MySQL 연결을 사용하여 모든 분류에 대해 쿼리합니다. MongoDB의 문서 스타일에 더 잘 맞도록 데이터를 비정규화하여 모든 테이블을 처리하도록 쉽게 확장할 수 있습니다. 분류 테이블에. 이 시점에서 우리는 분류 테이블의 모든 개별 항목을 사전으로 변환했으며, 이는 정확히 pymongo를 통해 MongoDB에 삽입하는 데 필요한 것입니다.

다음 샘플은 pymongo에 연결하고 사전을 pymongo에 삽입하는 방법을 보여줍니다.

import pymongo

client = pymongo.MongoClient('mongodb://192.0.2.2')

db = client['craigslist']
collection = db['classifieds']
collection.insert({'_id': 1})

이제 유일한 문제는 SQLAlchemy와 MongoDB가 ID를 지정하는 방법입니다. SQLAlchemy는 id 키를 사용합니다. 반면 MongoDB는 _id 키를 사용합니다. .따라서 해당 키를 번역해야 합니다(매우 간단한 프로세스):classified['_id'] = classified.pop('id') .

결론

SQL 및 NoSQL 데이터 저장소는 종종 전부 아니면 전무(all or nothing) 제안으로 묘사되지만 복잡한 문제를 해결하기 위해 함께 사용할 수 있음이 밝혀졌습니다. 이 예를 통해 MongoDB와 MySQL 데이터 저장소. 사실 이것은 데몬화되지 않고 cron에 의해 구동될 수 있습니다.

여러 데이터 저장소 활용의 어려움이 반드시 번역 코드 또는 마이그레이션 코드의 개발에 있는 것은 아니지만 추가 시스템을 관리하면 어려움이 증가합니다. 하나의 데이터 저장소를 유지하려면 이미 전문 지식(데이터 저장소 지식이 있는 DBA 또는 관리자)이 필요하며 이는 더 많은 데이터 저장소를 도입할수록 전문 지식에 대한 수요가 증가합니다.

기업은 여러 데이터 저장소를 실행하는 것이 가치가 있는지 결정해야 합니다. 이러한 문제를 완화하는 데 도움이 되는 기술이 있습니다.

Chef 및 Salt와 같은 자동화 기술 외에도 Rackspace의 관리형 MongoDB 서비스인 ObjectRocket과 같은 서비스 공급업체를 활용하면 이러한 문제를 완화할 수 있습니다. 복잡성이 증가하더라도 여러 데이터 저장소를 사용하면 문제가 해결될 수 있습니다. , 가정이 이러한 솔루션을 탐색하는 데 방해가 되지 않도록 하십시오.