[SQL] NoSQL

NoSQL

유래

  • RDB를 사용하지 않는다는 공통점만 있으면 MongoDB, CouchDB, 카산드라, LevelDB 등 저마다 다른 특성이 있다.

스크린샷 2021-09-22 20 19 02

  • 조핸 오스카슨의 RDB 사용하지 않는 연구에 대한 논의 트위터 해시태그 #NoSQL

배경

  • 2000년 초 웹 환경에서 발생하는 데이터를 다루기 위해 사용

스크린샷 2021-09-22 20 21 20

  • Web 시장의 발전과 함께 데이터 소스와 양이 폭발적으로 증가
  • 웹 서비스의 데이터는 xml, json으로 처리되는데 RDB로 처리하기에 오래 걸리기 시작
  • 하나의 서버를 크게 만드는 것보다, 여러 개의 서버를 연결 시켜 확장하는 방법이 비용 절감에 더욱 효과적 (수직 확장 -> 수평 확장)

RDB vs NoSQL

  • 만들어진 방식, 저장하는 정보의 종류, 저장하는 방법 등에 차이가 있다.
  • NoSQL은 데이터가 고정되어 있지 않은 DB 형태들을 주로 가리킨다.
  • RDB에서는 스키마가 뚜렷이 보이고 테이블 간의 관계를 알 수 있다.
  • RDB에서 데이터를 쓸 때 스키마에 맞춘다면, NoSQL은 스키마에 따라 데이터를 읽어온다.

차이점

Storage

  • RDB : SQL을 이용해 데이터를 테이블에 저장, 미리 작성된 스키마를 기반으로 정해진 형식에 맞게 저장
  • NoSQL : key-value, document, graph, wide-column 형식 등의 방식으로 데이터를 저장

Schema

  • SQL : 형식이 고정된 스키마 필요. 처리하려는 데이터 속성별로 열에 대한 정보가 미리 정해져야 한다는 의미. 스키마는 나중에 변경할 수 있지만, DB 전체를 수정하거나 오프라인으로 전환할 필요가 있다.
  • NoSQL : 스키마의 형태가 동적. 행을 추가할 때 즉시 열을 추가할 수 있고, 개별 속성에 대해 모든 열에 대한 데이터를 반드시 입력하지 않아도 된다는 장점이 있다.

Querying

  • 쿼리 : DB에 정보를 요청하는 행동을 의미
  • RDB : 테이블의 형식과 테이블간의 관계에 맞춰 데이터를 요청. SQL과 같은 구조화된 쿼리 언어를 정보 요청에 사용
  • NoSQL : 데이터 그룹 자체를 조회하는 것에 초점을 두고 있다. 구조화되지 않은 쿼리 언어로도 데이터 요청이 가능. -> UnQL(UnStructured Query Language)

Scalability

  • SQL : 수직적으로 확장(높은 메모리, CPU). 고비용. 복수의 서버에 걸쳐 DB 관계를 정의할 수 있지만 복잡하고 시간이 많이 소모
  • NoSQL : 수평적으로 확장(값싼 서버 증설, 클라우드 서비스 이용하는 확장). 많은 트래픽을 처리할 수 있도록 NoSQL DB를 위한 서버를 추가로 구축. 저렴한 범용 하드웨어나 클라우드 기반의 인스턴스에 NoSQL DB를 호스팅할 수 있어서, 수직적 확장보다 비용 효율성이 높다.

WHAT to CHOOSE

  • 완벽한 솔루션은 없다.
  • 많은 개발자는 서비스에 맞게 모두 사용한다.

SQL

  1. ACID 성질을 준수해야 하는 경우
    • 전자 상거래, 금융 서비스를 위한 소프트웨어 개발에서는 ACID가 필수 옵션
  2. 소프트웨어에 사용되는 데이터가 구조적이고 일관적인 경우
    • 많은 서버를 필요로 하지 않는 경우

NoSQL

  1. 데이터의 구조가 거의 또는 전혀 없는 대용량의 데이터를 저장하는 경우
  2. 클라우드 컴퓨팅 및 저장공간을 최대한 활용하는 경우
  3. 빠르게 서비스를 구축하고 데이터 구조를 자주 업데이트하는 경우

MongoDB

대표적인 NoSQL의 종류

스크린샷 2021-09-22 21 35 25

Key-Value

  • 데이터를 Key-Value의 쌍을 속성으로 하는 배열 형태로 저장
  • Key는 속성 이름, Value는 속성에 연결된 데이터 값
  • cf. Redis, Dynamo

Document DB

  • 문서처럼 저장하는 DB
  • JSON 유사 형식으로 데이터를 문서화
  • 각각의 문서는 하나의 속성에 대한 데이터를 갖고 있고, 컬렉션이라고 하는 그룹으로 묶어서 관리
  • cf. MongoDB

Wide-Column DB

  • coulmn에 대한 데이터 관리를 집중
  • 각 열에 key-value 형식으로 저장되고, 컬럼 패밀리라고 하는 열의 집합체 단위로 데이터 처리
  • 하나의 행에 많은 열을 포함할 수 있어서 높은 유연성을 자랑
  • 데이터 처리에 필요한 열을 유연하게 선택할 수 있다는 점에서 규모가 큰 데이터 분석에 주로 사용됨
  • cf. Cassandra, HBase

Document Databases

스크린샷 2021-09-22 21 41 12

  • 문서는 BSON 형태로 저장되고 정해진 틀이나 데이터 타입이 없다. -> 자유롭게 문자, 숫자 객체, 배열 등을 저장할 수 있다.
  • 사전에 정의된 테이블 필드나 관계에 맞출 필요 없이 데이터를 추가할 수 있다.
  • 보통은 일관되지 않은 데이터를 추가해야 하거나 재빠르게 데이터를 쌓아야 할 때 사용된다.

스크린샷 2021-09-22 21 42 39

  • SQL에 비해 데이터 타입이나 테이블 관계 등에서 비교적 자유가 있지만, 스키마가 아예 없는 것은 아니다.
  • 각 문서를 저장할 때 자유롭게 저장해도 되지만 그만큼 일종의 스키마가 있어야 수월하게 가져올 수 있다.

MongoDB Atlas

  • Atlas 로 클러스터 생성

스크린샷 2021-09-22 21 45 00

Pymongo

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
URI = 'mongodb+srv://6mini:*****@cluster0.buhiu.mongodb.net/myFirstDatabase?retryWrites=true&w=majority'

from pymongo import MongoClient
# print(MongoClient) # <class 'pymongo.mongo_client.MongoClient'>

client = MongoClient(URI)

# print(client)
'''
MongoClient(host=['cluster0-shard-00-00.buhiu.mongodb.net:27017', 'cluster0-shard-00-01.buhiu.mongodb.net:27017', 'cluster0-shard-00-02.buhiu.mongodb.net:27017'], document_class=dict, tz_aware=False, connect=True, retrywrites=True, w='majority', authsource='admin', replicaset='atlas-7sgtwy-shard-0', ssl=True)
'''

DB = 'myFirstDatabase'

db = client[DB] # 연결한 클라이언트 객체의 필드로 DB 생성/선택

COLL = '6mini-collection'

coll = db[COLL] # DB 콜렉션 조작

# print(coll)
'''
Collection(Database(MongoClient(host=['cluster0-shard-00-01.buhiu.mongodb.net:27017', 'cluster0-shard-00-02.buhiu.mongodb.net:27017', 'cluster0-shard-00-00.buhiu.mongodb.net:27017'], document_class=dict, tz_aware=False, connect=True, retrywrites=True, w='majority', authsource='admin', replicaset='atlas-7sgtwy-shard-0', ssl=True), 'myFirstDatabase'), '6mini-collection')
'''

coll.insert_one(document={'hello': '6mini'})

스크린샷 2021-09-22 22 04 37

  • 문서를 입력할 때 JSON 형태로 추가하면 된다.
  • SQL에서 Primary key를 이용해 레코드를 구분했다면 MongoDB에서는 각 문서에 고유번호를 부여한다.
    • _id 안에 ObjectId라는 값이 있다.
1
2
3
4
5
6
doc = coll.find_one()

print(doc)
'''
{'_id': ObjectId('614b28ec8ac8de52d42de5bd'), 'hello': '6mini'}
'''
  • 해당 고유번호는 변경할 수 있다. 임의로 정한 값이 될 수 있지만 중복되어서는 안 된다.
  • 추가 키워드
    • MongoDB local Install
    • MongoDB Cluster
    • CF NoSQL

Reference

0%