------

[ AD ] Port Monitor ( Try to use a Best WebSite Monitoring Tool )

------

클러스터드 인덱스를 어떤 컬럼(들)에 생성하는 것이 유리할까?
===========================================================

Sparse Index와 Dense Index의 개념은 다음과 같다.

- Sparse Index: 해당 레코드 존재 페이지를 가리키는 포인터를 저장
- Dense Index: 해당 레코드를 가리키는 포인터를 저장
- Heap : 데이터가 입력되는 순서에 따라 정렬되어 쌓이는 테이블 구조

MS-SQL Server에서는 Sparse Index를 클러스터드 인덱스라고 부르고, Dense Index를
논클러스터드 인덱스라고 부른다. DB2(UDB), Oracle은 Dense Index만을 지원하고,
MS-SQL Server, Sybase계열은 두 가지를 모두 지원한다. 구조상으로 기본구조는
Heap 또는 Dense Index로 구성되어야 한다. 구조상 그렇다. 여기에서는 MS-SQL Server를
다루도록 하것다.

그렇다면 클러스터드 인덱스(Sparse Index)와 논클러스터드 인덱스(Dense Index)를 어떤
기준으로 선정해야 할까? 아마도 MS나 Sybase의 DBMS를 만지고 있는 사람이라면 이런 고민
한번쯤은 해봤을 것이다.

보통은 이렇다.

- 범위검색에 많이 사용된다면 클러스터드 인덱스를 사용
- 포인트쿼리(1건 검색)에 많이 사용되거나 몇 건 안되는 컬럼(들)에 논클러스터드 인덱스 사용

회원번호, 가입일..... 과 같은 테이블이라면 뭐 대충 날짜에 생성해 넣는다.
대충 맞기는 하다. 하지만 범위검색 조건으로 서로 다른 컬럼이 생성된다면 어떤 컬럼을
클러스터드 인덱스로 잡을 것인가? 애매모호하다. 대부분 이런 경우다.


주문일, 결제일, 배송완료일 중 어느 컬럼에 클러스터드 인덱스를 잡을 것인가??
주문테이블(주문번호, 회원번호, 주문일, 결제일, 배송완료일...)

물론 이전에 설계가 잘 되었는지 살펴보아야 한다. 많은 경우 설계상으로 해결할 수도 있다.
뭐.. 대충 다음과 같은 따위로 해결 할 수 있다. 바로 주문상태테이블의 상태변경일에
클러스터드 인덱스 잡으면 해결된다.

주문테이블(주문번호, 회원번호)
주문상태테이블(주문번호, 상태코드, 상태변경일) //상태코드: 1(주문), 2(결제), 3(배송완료)

뭐..이렇게 해결할 수도 있지만 어쨌든 통합을 하면 유연해지지만 데이터양이 늘어날 수도 있고,
개체집합의 개념의 범위가 늘어남에 따른 문제(개념의 범위가 조낸 넓으면 관리상의 문제와
데이터 품질에 문제가 생길 수 있다.)가 발생할 수도 있다.

어쨌든 주문일, 결제일, 배송완료일 중 어느 컬럼에 클러스터드 인덱스를 잡을 것인가??라는
문제는 여전히 애매모호하다. 애매모호한 이유가 뭘까? 2가지다.

- 클러스터드 인덱스는 테이블당 1개만 생성 가능하다.
- 범위검색 조건으로 여러 개의 컬럼이 독립적으로 자주 사용된다.

어쨌든 변하지 않는 사실은 클러스터드 인덱스는 테이블 1개만 생성 가능'이다. (딴지 걸지 말자.
MS-SQL Server 2005의 인덱스 생성구문에 Inclued를 이용하면 2개의 클러스터드 인덱스 처럼의
흉내는 가능하지만 조낸 갱신부하 있다.) 어쨌든 클러스터드 인덱스를 생성할 컬럼을 선정해야 하기는
한다. 그렇다면 어떤 기준으로??

바로, "질의적중률" 이다. 질의 적중률은 다음과 같이 계산된다. (초딩 산수다..)

질의적중률 = 검색Row수/전체Row수

or

질의적중률 = 논리IO수/전체IO --> 요거 추천...


위의 예를 들어 보면...


A. SUM(주문일로 검색되는 질의들의 질의적중률) 계산
B. SUM(결제일로 검색되는 질의들의 질의적중률) 계산
C. SUM(배송완료일로 검색되는 질의들의 질의적중률) 계산

IF      A > B AND A > C THEN A(주문일)에 클러스터드 인덱스 생성
ELSE IF B > A AND B > C THEN B(배송일)에 클러스터드 인덱스 생성
ELSE IF C > A AND C > B THEN C(배송완료일)에 클러스터드 인덱스 생성


끝이다. 조낸 간단하다. 결론은 질의적중률이 높은 컬럼(들)에 클러스터드 인덱스를 생성하면 유리하다.
요런게 왜 DBMS책에 안나오는 걸까?


http://www.webmadang.net/database/database.do?action=read&boardid=4001&page=1&seq=23

두 테이블간의 컬럼이 일치하지 않을때 SELECT INSERT 하기

두개의 테이블간에 컬럼이 table_a 와 table _c 처럼 일치하지 않을때는 아래와 같이 컬럼명을 지정해 주시면됩니다.
-- 사용법

INSERT INTO [입력될 테이블명] (컬럼1, 컬럼2, ... ) SELECT 컬럼1, 컬럼2, ... FROM [검색되는 테이블명]

예3) INSERT INTO table_c ( seq, Name, Email, Idate ) SELECT seq, Name, Email, Idate FROM table_a

위의 예3) 에서는 table_a 의 컬럼중 seq, Name, Email, Idate 컬럼을 table_c 에 Insert 시키고 있습니다. 한가지 주의
할 것은 table_c 의 구조가 table_b 와 다른 만큼 INSERT 될 컬럼이 SELECT 되는 컬럼과 일치하지 않으면 아래와 같은
에러가 발생하게 됩니다.

서버: 메시지 213, 수준 16, 상태 4, 줄 1
삽입 오류: 제공된 값의 개수나 열 이름이 테이블 정의와 일치하지 않습니다.


GetLastError() -> 문자열 메시지 창으로


  

LPVOID lpMsgBuf;

  FormatMessage (
   FORMAT_MESSAGE_ALLOCATE_BUFFER |
   FORMAT_MESSAGE_FROM_SYSTEM |
   FORMAT_MESSAGE_IGNORE_INSERTS,
   NULL,
   GetLastError (),
   MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT), // 기본 언어
   (LPTSTR) & lpMsgBuf,
   0,
   NULL
   );

  MessageBox (NULL, (LPCTSTR) lpMsgBuf, L"Error", MB_OK | MB_ICONINFORMATION);


  LocalFree (lpMsgBuf);







CString을 non MFC에서 사용하기 위해

MS VS 2003부터 atlstr.h로 분리 되었다고 함.

'온라인게임' 카테고리의 다른 글

MS SQL 컬럼이 일치하지 않을때 SELECT INSERT 하기  (0) 2010.11.25
GetLastError() -> 문자열 메시지 창으로  (0) 2010.11.25
카트라이더  (0) 2010.11.24
온라인 게임 서버 설계  (0) 2010.11.24
몇가지 요소  (0) 2010.11.24
요인1.
잘 할 수 있는 것에 집중하라

요인2.
단순하게 만들되 기본에 충실하라

레이싱 게임은 결코 쉬운 게임이 아니다.
레이싱 게임의 성패는 얼마나 실제 자동차 경주와 비슷하게 재현하는 가에 달려 있다는 것이 통념------------뒤지버..

카트라이더는 기존 생각을 완전히 뒤업고 Shift, Ctrl키와 화살표 키만으로 방향과 속도 조절이 가능
한번의 게임시간이 5분이 넘지 않도록 한다.

- 조작을 단순화 하고 한번의 게임에 들이는 시간을 줄임 ,,, 여성과 직장인들을 끌어들인것.

시간을 줄임으로 재미가 줄어드는 요소는 게임머가 상대방을 제칠 때 나타나는 그래픽 효과를 극대화 하는 방법으로 보완


요인3.
익숙한 것을 활용하되 새롭게 하라.

마리오카트를 표절했다는 의혹, 혁신적이지 못하다. -- 게임머가 쉽게 게임에 접근 할 수 있다는 장점

다른 게임과의 차별성 없지만,,,,, 다양한 잔재미를 배치해 사용자를 자극

-- 라이선스 제도 - 고수들과 실력을 겨룰 수 있도록 한것
-- 아이템전 과 레이싱전  - 다양한 경험 .... 패턴....
-- 카트 꾸미기, 물풍선 아이템
-- 루찌 머니 - 성능 좋은 카트
--



http://blog.naver.com/fallskya/100012923840


'온라인게임' 카테고리의 다른 글

GetLastError() -> 문자열 메시지 창으로  (0) 2010.11.25
CString #include <atlstr.h>  (0) 2010.11.25
온라인 게임 서버 설계  (0) 2010.11.24
몇가지 요소  (0) 2010.11.24
SQL Server 2005/2008 Express Edition  (0) 2010.11.23

온라인 게임 서버 설계

[세션 Session]
EventHandler , Socket

[엔티티 Entity]
User, Player, Monster





http://sazabis.egloos.com/4719270



장점
1. 구조가 비교적 단순하여 직관성이 향상된다.
2. 엔진이 알고 있는 세션을 직접 상속하므로 접근성이 확대된다.
3. 디버깅이 효율적이다.


단점
1. 서버 엔진의 구현에 참여된 세션이 그대로 로직에 노출된다.
2. 상속 구조를 가지므로 서버 엔진과 로직의 의존관계가 이루어진다.
3. 엔티티는 세션과 is-a 관계로 불필요한 책임을 가지게 된다. [단일 책임 원칙(SRP) 위반]





구현된 게임 서버 엔진

[IO Coordinator]
실제 서버 엔진 Network I/O Layer 에서 발생한 여러가지 이벤트를
UserLayer 즉, 로직에 알리는 역할을 가진 클래스입니다.

[Entity]
서버 엔진이 알고있는 주체와의 연관 관계를 위해 설계된 클래스입니다.
실제로 서버 엔진을 사용하게 되는 유저, 즉 로직은 EventHandler[Session] 을 알지 못하고
오직 Entity 클래스만을 알도록 설계적으로 노출시키도록 하였습니다.

그리고 서버 엔진에서 로직으로, 그리고 로직에서 엔진으로 요구하는 여러가지 명령에 대해
각각의 주체를 공유하기 위한 Unique ID 를 생성해 관리하며 처리합니다.

그리고 서버 엔진에서 로직으로, 그리고 로직에서 엔진으로 요구하는 여러가지 명령에 대해
각각의 주체를 공유하기 위한 Unique ID 를 생성해 관리하며 처리합니다.

즉, 위 구성(그림 1, 2) 과는 다르게 세션과 엔티티 클래스의 상속 관계를 제거하였습니다.
따라서 로직이 알 필요가 없는 세션 클래스의 역할 자체를 노출할 필요가 없게 되었으며,
로직에서 엔진쪽으로 접근이 필요한 인터페이스에 대해서는 엔티티 클래스가 그 역할을
가지게 하여 프록시 패턴의 형태로 구성이 됩니다.

따라서, 의존관계가 사라지므로 각 레이어의 주체 클래스(엔진:Session, 로직:Entity) 의
영역을 제거하거나 혹은 직접적인 접근이 이루어지더라도 각각에게는 아무런 영향이
없는 것입니다.

Entity 클래스 역시도 서버 엔진 구성에 포함되는 클래스이지만, 로직에 노출되는 클래스는
엔티티 클래스로 제한됩니다.

그리고 로직은 엔티티 클래스를 상속 받거나 혹은 이 역시도 불필요한 구성이므로
오직 Unique ID 를 통해 [연결] [종료] [수신] [송신]에 대한 요구와 통보 처리만
노출시키도록 해도 되겠지요.


장점
1. 서버 엔진과 로직 간의 의존관계가 사라진다.
2. 서버 엔진에 참여한 세션 클래스의 기능을 불필요하게 로직에 노출하지 않게 된다.
3. 세션은 세션의 역할, 엔티티는 엔티티의 역할만을 수행하므로 역할이 분명해진다.


단점
1. 구조가 복잡해지므로 구조를 이해하기 전 까지 직관성이 떨어질 수 있다.
2. 프록시 클래스가 추가되므로 개발 자체에 대한 비용은 증가한다.
3. 디버깅이 어렵다.




댓글상에... 게임서버 상용 엔진 proudnet / www.nettention.co.kr

'온라인게임' 카테고리의 다른 글

CString #include <atlstr.h>  (0) 2010.11.25
카트라이더  (0) 2010.11.24
몇가지 요소  (0) 2010.11.24
SQL Server 2005/2008 Express Edition  (0) 2010.11.23
CString 형 변환  (0) 2010.11.19
안철수 KAIST 교수가 2010.11.16 서울 프라자호텔에서 열린
'2010 대한민국 모바일앱 개발자 컨퍼런스' 기조연설을 통해 밝힌
성공적인 창업의 조건이다.

" 적합한 사람들이 모여라.
만들고 싶은 제품이 아니라 사용자가 원하는 좋은 제품을 만들어라.
한꺼번에 하려고 하지 말고 점진적으로 하라."

'좋은 제품'이란 창업자나 기술자가 만들고 싶은, 만들 수 있는 제품이 아니라 시장과 사용자가 원하는 제품이다.
"창업자 스스로 사용자가 원하는 제품을 만들었다고 판단하나 아닐 수 있다"
"처음에는 2~3개의 아이템이 아닌 하나에 '올인'해야 한다"

 "1단계가 검증되면 추가로 사람을 뽑고 자금을 써 다음 단계로 가야한다"며
"점진적으로 해야 성공확률이 높아지고 2단계, 3단계 실패해도 재도전할 수 있다"

'온라인게임' 카테고리의 다른 글

카트라이더  (0) 2010.11.24
온라인 게임 서버 설계  (0) 2010.11.24
SQL Server 2005/2008 Express Edition  (0) 2010.11.23
CString 형 변환  (0) 2010.11.19
상호 참조 / 종속성 문제를 회피하기 위한 인터페이스  (0) 2010.11.18
SQL Server 2005/2008 Express Edition의 프로필러 Profiler / Performance Tool / Express 제외

마이크로 SQL 서버 패밀리는 무료 간단 버젼을 포함한다.  간단 버젼은 모든 기능을 한다.

그러나 몇가지 실망하게한느 제한사항을 갖고 있다. 개발 과정에서 사용하는 것을 막는다.

프로필링 툴의 공백은 그중에 하나로, 표준 SQL 프로필러가 포함되지 않았다.

그러나  바로 시스템 튜닝을 위한 간단 버젼을 사용하는 능력을 가질 수 있다.

SQL Server Express Editon Profiler는 표준 profiler가 하는 것들을 제공한다.
이벤트 선택하여 프로파일, 필터 설정 등등

[AnjLab Sql Express Profiler]
1.5MB의 크기로 최신 버젼을 받을 수 있다
소스 코드도 받을 수 있다.

http://code.google.com/p/sqlexpressprofiler/downloads/list



도움 되시면..좋겠네요..

CString 형 변환

CString -> BYTE

BYTE*   temp;
CString   cmd;
에서 cmd 의 값을 temp에 할당하려 할때.

 

temp=new BYTE[255];
temp=(LPBYTE)(LPCSTR)cmd;
delete []temp;

 

or

 

CString str = _T("abcd");
BYTE* pbyte = new BYTE[256];
int nSize;
nSize = str.GetLength();
CopyMemory( pbyte, str.GetBuffer(nSize), nSize );
pbyte[nSize] = 0;

 

or

 

strcpy(szNamePlace,(LPCTSTR)name);


or

 

CString str = "string";
BYTE* pByte;
pByte = (BYTE*)(LPTSTR)(LPCTSTR)str;



 

BYTE -> CString


 

CString testString;
BYTE    testByte;
testString.Format( "%s", testByte );




http://rainbird.springnote.com/pages/152001?print=1


상호 참조 / 종속성 문제를 회피하기 위한 인터페이스

ICallerSink.h
class ICallerSink
{
public:
	virtual ~ICallerSink(){};
	virtual bool CallBackMe(const char *lpText)=0;
};

Caller.h
#pragma once

#include "ICallerSink.h"

class Caller : public ICallerSink
{
public:
	Caller();
	virtual ~Caller();
	bool CallService();
	virtual bool CallBackMe(const char * lpText);
};

Caller.cpp
#pragma once

#include "StdAfx.h"

#include "Caller.h"
#include "Callee.h"

#include 

Caller::Caller(void)
{
}

Caller::~Caller()
{

}


bool Caller::CallService()
{
	Callee service;
	service.DoSomething(this);
	return true;
}

bool Caller::CallBackMe( const char* lpText )
{
	std::cout << "call back : " << lpText << std::endl;

	return true;
}



Callee.h
#pragma once

//#include "ICallerSink.h"

class ICallerSink;

class Callee
{
public:
	Callee();
	virtual ~Callee(void);
	bool DoSomething(ICallerSink *pSink);
};



Callee.cpp
#include "StdAfx.h"
#include "Callee.h"

#include "ICallerSink.h"

#include 

Callee::Callee(void)
{
}


Callee::~Callee(void)
{
}

bool Callee::DoSomething(ICallerSink *pSink)
{
	std::cout << "Callee.DoSomething" << std::endl;

	pSink->CallBackMe("호출을 아래에서 위로...");

	return true;
}


+ Recent posts