각 플레이어의 로컬 컴퓨터에 플레이어 정보를 저장하면?
- 플레이어가 자리를 옮겼을 때 자기가 플레이하던 정보를 이어서 할 수 없음
- 플레이어가 해킹을 할 줄 안다면, 자기가 컴퓨터에 저장된 플레이 정보를 조작할 수 있음
플레이어 정보를 서버에 저장하는 방법: 파일과 데이터 베이스
- 상용으로 서비스되는 게임들은 대부분 플레이어 정보를 데이터베이스에 저장함
파일 vs 데이터베이스
- 데이터베이스는 구체적인 상황에서도 빠르고 다각적으로 데이터 검색할 수 있음
데이터베이스 구성
- 데이터베이스에서 다루는 데이터는 표 형태의 집합
- 데이터베이스 인스턴스: 테이블의 집합으로 데이터베이스가 다루는 가장 큰 단위의 데이터 집합
- 데이터베이스에서는 행 단위로 데이터를 넣거나 뺄 수 있으며 이 행을 레코드라 함
- 레코드 안에는 표의 열이 있는데, 이를 필드라고 함
- 필드는 이름 말고도 타입이라는 것을 추가로 가지고 있으며, 타입은 다음 중 하나임
CRUD (Create, Read, Update, Delete)
: 레코드 추가하기, 읽기, 변경(업데이트), 삭제하기
- table1에 있는 레코드 중 필드 a가 1인 것을 모두 삭제
데이터베이스에서 인덱스 기능 사용하기
- 인덱스는 필드 단위로 설정할 수 있음
- 인덱스를 설정해 놓으면 특정 조건에서 어마어마하게 빠른 속도로 원하는 레코드를 찾을 수 있음
- 인덱스는 select 구문, 즉 검색만을 위한 것이 아님
- 기존 레코드를 변경하거나 레코드를 삭제할 때도 인덱스는 빨리 찾는데 큰 도움이 됨
- 중복된 값을 방지하는 용도로도 사용됨
프라이머리 키
- 한 테이블에 하나만 추가할 수 있음
- 중복을 허락하지 않음
- 필드 값은 null이 허락되지 않음
구조체형 데이터를 테이블에 저장하는 방법
- 플레이어 데이터 전체를 문서 형태로 만들어서 테이블에 넣음 ex) JSON, xml
- 플레이어 데이터를 구성하는 트리 노드 각각을 테이블에 넣음
게임 서버가 데이터베이스에 질의 구문을 자주 던지는 것은 비효율적
- 질의 구문 던지기 후 결과 받기 과정이 수행되는 동안 디바이스 타임이 발생
- 게임 서버와 데이터베이스 간 네트워크 레이턴시를 다 모으면 꽤 긴 시간이 됨
저장 프로시저
: 데이터베이스 안에서 직접 실행되는 스크립트 프로그램
- EXEC 다음에 저장 프로시저 이름과 입력할 매개변수를 나열하면, 데이터베이스는 저장 프로시저 안에 있는 많은 구문을 알아서 다 실행함
두 질의 구문은 반드시 A -> B 순서로 액세스
- 데이터베이스 트랜잭션을 할 때는 꼭 필요한 최소한의 구간에서만 하는 것이 좋음
- 트랜잭션의 영향을 받는 레코드는 최소 개수로 하고, 트랜잭션을 시작부터 끝날 때까지 데이터를 액세스하는 횟수 역시 최소로 함
- 교착 상태로 질의 구문 실행이 매우 오랫동안 블로킹되거나 실패를 출력할 때도 반드시 별도로 처리해 주어야 함
- 트랜잭션이 관여되는 레코드는 다른 질의 구문 프로세스에서 액세스할 경우 블로킹을 일으켜 병렬 처리 효율성이 떨어짐
- 게임 서버는 플레이어 정보를 메모리에 보관하고, 플레이어의 데이터를 게임 서버 안에 있는 메모리에서 변경하며, 변경된 내용을 데이터베이스에 저장함
- 게임 서버 안 메모리가 연산의 주요 대상이므로 두 플레이어 간 아이템 거래 같은 중요한 처리도 게임 서버 안 메모리에서 모두 판정이 끝난 후 뒤늦게 데이터베이스에 기록됨
레코드를 2개 이상 기록하되 전부 아니면 전무하게 기록하는 동시에 트랜잭션을 사용하기 어려운 상황이라면?
- 어딘가에 로그를 남겨 놓고 두 플레이어의 레코드를 업데이트, 그리고 두 레코드의 업데이트가 완료되면 해당 로그를 지워버림
- 트랜잭션에서 발생하는 잠금 수준을 완화
- 트랜잭션의 잠금 수준을 "다른 곳에서도 읽는 것을 허락한다"라고 변경
상업용 게임 서비스를 정식 오픈하고 나서 종종 겪는 상황들
- 게임 서버가 플레이어 정보를 메모리에 항상 보관하고 있음
- 플레이 처리의 주체는 게임 서버 내부의 메모리 안에서 이루어짐
- 데이터베이스는 세이브 데이터 역할 정도만 함
ORM (객체 관계 매핑, Object - Relational Mapping)
- 데이터베이스 우선 방법: 데이터베이스 테이블이나 필드를 정의하면, 이 테이블을 편하게 액세스할 수 있는 데이터베이스 액세스 클래스들이 생성됨
- 코드 우선 방법: 데이터베이스를 액세스할 클래스를 정의하고, 클래스 안에는 사용할 멤버 변수들을 정의함, 그러면 정의한 클래스 구조에 따라 데이터베이스가 생성되거나 변경됨
'Old > 복습' 카테고리의 다른 글
C++ - 범위 기반 for문 (1) | 2024.01.03 |
---|---|
C++ - 생성자와 소멸자 (0) | 2023.12.27 |
운영체제 - Call Stack (0) | 2023.12.27 |
운영체제 - Thread (0) | 2023.12.27 |
게임 서버 - 관계형 데이터베이스와 NoSQL (1) | 2023.08.16 |