해당 블로그의 내용은 게임 서버 프로그래밍 교과서의 내용을 요약, 정리한 내용입니다.

관계형 데이터베이스와 NoSQL

관계형 데이터베이스(SQL, RDBMS)는 특정한 상황에서 몇 가지 부족한 점이 있다.

한 테이블에 저장된 레코드들은 모두 같은 형태의 필드를 가져야 한다.
만약 원하는 형태로 레코드가 쌓였는데, 게임을 유지보수 하다가 필드를 추가해야 하는 상황이 생긴다면, 기존에 쌓여있던 모든 레코드들에 필드를 추가해야 한다.

기존 테이블 구조를 바꾸는 일은 복잡하다. 또한 데이터베이스 입장에서도 많은 양의 처리를 단시간에 해야 하는 일이다.
또한 관계형 데이터베이스는 여러 종류의 테이블에 나누어서 저장하는 방식이다. 하지만 프로그램 구조가 복잡해질수록 테이블 구조도 변경해야 한다.

관계형 데이터베이스에서 확장성

또한, 만약 게임 서비스를 이용하는 유저가 어마어마하게 많다면, 데이터베이스에 접속하는 일도 어마어마하게 많아진다. 따라서 플레이어 정보를 여러 대에 나누어서 저장한다.

플레이어 정보가 테이블 여러 개에 저장되어 있으면 나누기 쉬워진다. 여러 테이블을 여러 데이터베이스에 각각 나누면 된다. 이를 수직분산이라 한다.

하지만수직 분산은 한계가 있다. 테이블이 10개인데 100개의 컴퓨터에 나누어 담을수는 없다.

이러한 경우는 데이터를 수평분산하는 것이 좋다.
레코드가 1억개이고, 컴퓨터가 100대라면, 각각의 컴퓨터에 100만개의 레코드를 분배하는 방식이다.
각 컴퓨터가 큰 테이블 1개를 조각조각 가지는 방식이며, 이를 샤드라고 한다.

이 상태에서 데이터베이스에 액세스하려면, 해당 레코드가 어드 샤드에 있는지 파악해야 한다.
이를 위한 방법은 두 가지가 있다.

  • 해시 함수를 사용하여 연산 후 얻은 값을 샤드 넘버로 사용한다.
  • 로케이터 DB를 사용하여 어느 샤드에 저장되어있는지를 담고 있는 별도의 테이블에 액세스한다.

JSON

나무위키

MongoDB

MongoDB는 JSON을 적극 활용한다.
몇 가지 용어의 차이는

  • RDBMS에서 DB인스턴스라고 부르는 것은 MongoDB에서도 똑같이 부른다.
  • RDBMS의 DB인스턴스 안에는 테이블이 있다. MongoDB의 인스턴스 안에는 컬렉션이 있다.
  • RDBMS의 테이블 안에는 레코드가 있다.MongoDB에서는 컬렉션 안에 레코드 대신 도큐먼트가 들어간다.

MongoDB의 도큐먼트에는 데이터 트리를 저장한다.

MongoDB에 데이터 액세스

MongoDB와 같이 설치할 수 있는 MongoDB Compass를 이용하면 컬렉션과 도큐먼트를 쉽게 조작할 수 있다. 하지만 여기서는 명령어로 데이터에 액세스 한다.

생성(create)

db.<COLLNAME>.insert(<OBJECT>)

이런 식으로 하면 COLLNAME에 적은 컬렉션에 JSON형식으로 작성한 OBJECT가 들어간다.

db.coll1.insert({"a":2})
db.coll1.insert({"a":3})

읽기(read)

db.<COLLNAME>.find(<COND>)
db.<COLLNAME>.findOne(<COND>)

COND에서는 찾기 조건문을 넣으면 된다.
COLLNAME을 가진 컬렉션에서 COND 조건을 만족하는 데이터를 찾는다.
findOne을 이용하면 첫번째로 나오는 하나만 출력한다.

db.coll1.find({"a":{$gt:1}});			//a가 1보다 큰 데이터를 가져온다.
db.coll1.find({$or:[{"a":1},{"a":2}]});	//a가 1이거나 2인 데이터를 가져온다.

업데이트(update)

db.coll1.update({"a":1},{$set:{"a":5}})

이는 a=1인 것을 찾아 a=5로 바꾼다는 의미이다.

지우기(delete)

db.coll1.remove({"a":3})

a=3인 도큐먼트를 지운다는 의미이다.

성능 분석 기능

MongoDB에서는 실행 구문 오른쪽에 .explain("executionStats")구문을 넣으면 성능 통계정보가 나온다.

관계형 데이터베이스에는 인덱스가 특정 필드 값을 가진 레코드를 매우 빠르게 찾아준다.
MongoDB에서는 key값에 인덱스를 추가할 수 있다. ensureIndex()를 사용한다.

profile
코린이

0개의 댓글