7.데이터베이스의 기초
플레이어의 정보 저장
온라인 게임에서 로컬 컴퓨터에 플레이어 정보를 저장시 문제점
- 플레이어가 자리를 옮겼을 때 자기가 플레이하던 정보를 이어서 할 수 없음
- 플레이어가 해킹을 할 줄 안다면, 자기가 컴퓨터에 저장된 플레이 정보 조작가능성
데이터베이스 사용이유
- 데이터 관리, 분석 속도가 빠르다
- 데이터 백업 및 복원기능 존재
- Transaction ACID 제공
데이터베이스의 데이터 구성
- 인스턴스 : 테이블 집합
- 레코드 : 행
- 필드 : 열
데이터베이스의 필드타입
- 저장되는 필드의 글자 수에는 제한이 있다
- TEXT는 제한이 없지만 엑세스 속도가 늦다
- NULL은 '0'이 아니라 값 자체가 없는 것
SQL 질의 구문
CURD(레코드의 추가, 읽기 , 변경 , 삭제)
- INSERT INTO TABLE ('type','type','type') VALUES (V1,V2,V3)
- SELECT * FROM TABLE WHERE 조건
- UPDATE TABLE set 값 변경 WHERE 조건
- DELETE FROM TABLE WHERE 조건
인덱스와 키
특징
- 필드 단위로 설정
- 특정 조건에서 엄청나게 빠른 속도로 검색 가능
- 검색뿐만아니라 추가 삭제도 빠름
- 테이블 하나에 여러개의 인덱스 추가 가능
- 레코드 둘 이상을 찾아 정렬하는 용도로 사용 가능
- 중복된 값을 방지하는 용도로 사용 가능 (Unique 속성)
- 인덱스가 걸쳐 있는 레코드에 변화가 일어날 때, 인덱스도 같이 업데이트 해야 함
- 기록할 때 더많은 시간이 걸림
- 가급적 인덱스를 거는걸 피해야 함
프라이머리 키
- 특수한 형태의 인덱스
- 한 테이블에 하나만 존재
- 중복 허락 하지않음
- 필드 값은 null을 허락 하지않음
플레이어 정보를 데이터베이스에 저장하는 법
플레이어 데이터는 구조체와 목록의 집합
구조체형 데이터를 테이블에 저장하는 법
플레이어 데이터 전체를 문서 형태로 만들어 테이블에 넣는 방법
- JSON,XML 형태로 생성
- 이해하기 쉬운 방법
- 원하는 조건 값을 자주 찾아야할 때는 한계를 가짐
플레이어 데이터를 구성하는 트리 노드 각각을 테이블에 넣는 방법
- 인덱스나 프라이머리키로 중복되지않는 키 설정
- 외래키를 통해 다른 테이블 접근
외래키
정의
테이블의 어떤 필드가 다른 테이블의 특정 필드 값을 가리키는 것
사용이유
데이터베이스의 어떤 테이블을 넣어야 할지 계획을 잡을 때 자주 사용
외래키를 통해 CUID를 자주 한다.
질의 구문 실행
게임 서버가 데이터베이스에 질의 구문을 자주 던지는 것은 비효율적
- 디바이스 타임 발생
- 레이턴시가 꽤 많이 생김
저장 프로시저의 이용
데이터베이스 안에서 직접 실행되는 스크립트 프로그램
트랜잭션
- ACID 보장
begin transaction update UserAccount set Money=Money+100 where ID='KANG BU JA' update UserAccount set Money=Money-100 where ID='HONG GIL DONG' commit or rollback transaction
- commit시 두 update 구문은 데이터베이스에 영구적으로 저장
- rollback transaction을 하면 변경 데이터가 모조리 원상 복구
데드락
데드락을 피하는 방법
- 트랜잭션은 최소한의 구간에서만 사용
- 트랜잭션의 영향을 받는 레코드는 최소개수로 한다
- 트랜잭션을 시작부터 끝날 때까지 데이터를 엑세스하는 횟수를 최소화
- 교착상태에 따른 예외 처리를 한다
게임서버에서의 트랜젝션
- 데이터베이스를 세이브 데이터처럼 사용
- 게임 서버 안 메모리에서 모두 판정이 끝난 후 뒤늦게 데이터베이스에 기록
- 게임 서버에서 그렇게까지 트랜잭션이 필요하지 않다
트랜젝션으로 발생하는 성능 저하와 데드락 가능성을 완전히 제거하려면
- 로그를 남기고 두 플레이어의 레코드를 업데이트
- 트랜잭션의 잠금수준 완화
게임 서버에서 질의 구문 실행
사용 가능한 데이터베이스 연결 모듈 혹은 데이터베이스 클라이언트 모듈 사용
- db 연결
DbConnection db = new DbConnection(); // 연결에 Data Server 주소, 사용할 데이터베이스 인스턴스 이름,사용자 ID,PASSWORD 필요 db.Open("server=db01.mygame.com;userid=serverbot;password=good_day_one; database=GameDB");
- db 실행
DbCommand cmd = new DbCommand(db); cmd.Execute("insert into table1 (a,b,c) values (123,456,789)"); //추천하는 방법 (보안성) DbCommand cmd = new DbCommand(db); cmd.Parameters[0] = 123; cmd.Parameters[1] = 456; cmd.Parameters[2] = 789; cmd.Execute("InsertRecord");
- db 로드
DbCommand cmd = new DbCommand(db); cmd.Parameters[0] = 123; // ?에늩 Parameters[0] 의 값이 자동으로 들어간다 DbRecordset rs = cmd.Execute("select (a,b,c) from table1 where a>=?");
보안을 위한 주의사항
- 데이터베이스의 모든 것을 다룰 수 있는 관리자 계정은 오직 관리자만 직접 다룰 수 있게 한다
- 게임 서버가 사용하는 계정은 게임 서버가 다루는 테이블 이외에는 건드리지 못하게 한다
'게임 서버 프로그래밍 > 게임 서버 프로그래밍 교과서' 카테고리의 다른 글
#9. 분산 서버 구조 (0) | 2020.02.17 |
---|---|
#8. NOSQL (1) | 2020.02.17 |
#6. 프라우드넷 (0) | 2020.02.17 |
#5. 게임 네트워크 (0) | 2020.02.17 |
#4. 게임 서버와 클라이언트 (0) | 2020.02.17 |