서버 개발/프로그래머를 위한 RDBMS

DB 절차적 사고 VS 집합적 사고

지노윈 2020. 5. 27. 10:32
반응형

절차적으로 개발하면 하나 하나에 대한 처리를 던지므로 옵티마이저는 최적화 할 것이 거의 없습니다. (노가다만 하는 거죠)

 

조회 후 업데이트 또는 입력

select.Execute()
while (select.Fetch())
{
	if(조건?)
	{
		update테이블.Execute();
	}
	else
	{
		insert테이블.Execute();
	}
}
merge 테이블
using (select ...) 
on ( 조건 )
when matched then
	update ...
when not matched then
	insert ...

 

아이템 강화의 예

for(재료 아이템 종류)
{
	if(아이템이 0개인가?)
	{
		delete아이템.Execute();
	}
	else
	{
		update아이템수.Execute();
	}
}
update유저보유금액.Execute();
update아이템등급.Execute();

위 코드의 Execute()가 실행 되는 도중에 하나라도 실패하면 어떻게 할 것인가? 아찔하죠~

또 다시 복구 실행을 해야 하죠. 그런데 복구 실행 마저 실패 한다면 어떻게 해야 하죠?

이 상태로 서비스 하면 안된다 싶어서 데이터베이스 실행이 실패하면 심지어는 서버 크래시를 발생 시키는 게임 서버도 있죠.

우리가 값비싼 데이터베이스를 사용하는 이유는 이러한 데이터 무결성 처리를 데이터베이스의 transaction 기능을 이용하면 너무 간결하게 해결이 됩니다.

 

집합적으로 구현하면 아래와 같습니다. 코드도 한결 간결해 졌습니다.

DBCommand<SP::update아이템강화> 강화;
강화.Execute();

먼저 array type을 정의하고 재료를 모두 array로 넘깁니다. transaction을 이용해서 오류에 대한 대비도 해주었고요.

create type dbo.ItemList as table
(
	dbId bigint,
	count int
);

CREATE PROCEDURE dbo.update아이템강화
	@강화아이템Id int,
	@재료아이템목록 AS dbo.ItemList READONLY,
	@비용 BIGINT,
AS
BEGIN
	...

	begin tran

	update 유저 set money = money - @비용
	merge 아이템 as A
	using (select dbId, 수량 from @재료아이템목록) as B
	on (A.dbId = B.dbId)
	when match and A.count > B.count then
		update count -= B.count
	when match and A.count <= B.count then
		delete
	
	update 아이템 set grade = grade + 1 where dbId = @강화아이템Id
	commit

	...
END

 

 

SQL을 절차형으로 작성하면 전체의 흐름이 프로그래밍으로 구현되며 이를 개선하려면 전체적인 로직을 다시 작성해야 합니다.

그렇지만 SQL로 집합적으로 개발이 되면 SQL을 조금만 수정해도 크게 성능이 개선 될 수 있습니다.

 

SQL 위주로 작성된 프로그램은

  • 프로그램이 매우 단순, 명료해진다.
  • 처리과정을 기술하지 않고 결과만 요구한 문장이므로 이해하기 쉽다.
  • 약간의 수정(SQL, INDEX등)만으로도 처리방법이 달라지므로 개선이 쉽다.
  • 데이터 모델이 변경되더라도 원하는 결과는 달라지지 않으므로 수정이 적다
  • 고급 SQL 생성 능력을 키우는 것이 힘들지만 수준에 도달하면 대단한 생산성 보장

SQL은 Statement가 아니라 Application입니다. 수천줄의 프로그램을 대신 할 수 있는 어플리케이션입니다.

데이터데이스에게 일일 시킬 수 있는 유일한 방법이며 절차형 사고를 집합적 사고로 전환해야 합니다.

동일한 결과를 내는 처리 경로는 많으나 효율의 차이가 큽니다.

응용력에 따른 개이차 큽니다.

 

사용상의 미묘한 차이가 엄청난 차이가 납니다.

1000줄의 코드를 10줄의 sql로 만들 수도 있습니다.

1000초의 수행 속도를 약간의 변경 만으로도 1초로 만들 수 있습니다.

내부 처리절차를 모르는 사람은 세월이 흘러도 제자리입니다.

원리 이해를 바탕으로 정석을 익히고 응용력을 키워야 겠습니다.

 

[데이터베이스/게임 서버 프로그래머가 알아야 할 RDBMS] - 게임 서버 프로그래머가 알아야 할 RDBMS

[데이터베이스/게임 서버 프로그래머가 알아야 할 RDBMS] - 옵티마이저 맛보기

[데이터베이스/게임 서버 프로그래머가 알아야 할 RDBMS] - 테이블 조인 하면 느리다?

[데이터베이스/게임 서버 프로그래머가 알아야 할 RDBMS] - 리커시브 모델의 활용

[데이터베이스/게임 서버 프로그래머가 알아야 할 RDBMS] - 아크 모델(exclusive or)에서의 주의점

[데이터베이스/게임 서버 프로그래머가 알아야 할 RDBMS] - 부분범위 처리와 전체 범위처리

[데이터베이스/게임 서버 프로그래머가 알아야 할 RDBMS] - 인덱스의 제대 사용하자

[데이터베이스/게임 서버 프로그래머가 알아야 할 RDBMS] - DB 옵티마이저

[데이터베이스/게임 서버 프로그래머가 알아야 할 RDBMS] - Nested Loop/Sort Merge/Hash Join

[데이터베이스/게임 서버 프로그래머가 알아야 할 RDBMS] - DB 테이블 클러스터링 팩터

[데이터베이스/게임 서버 프로그래머가 알아야 할 RDBMS] - DB 절차적 사고 VS 집합적 사고

[데이터베이스/게임 서버 프로그래머가 알아야 할 RDBMS] - SQL 집합의 가공

[데이터베이스/게임 서버 프로그래머가 알아야 할 RDBMS] - SQL IN의 특징과 IN의 활용

[데이터베이스/게임 서버 프로그래머가 알아야 할 RDBMS] - 서브 쿼리 활용

[데이터베이스/게임 서버 프로그래머가 알아야 할 RDBMS] - 인라인 뷰의 활용

 

'서버 개발 > 프로그래머를 위한 RDBMS' 카테고리의 다른 글

SQL IN의 특징과 IN의 활용  (0) 2020.05.27
SQL 집합의 가공  (0) 2020.05.27
DB 테이블 클러스터링 팩터  (0) 2020.05.27
Nested Loop/Sort Merge/Hash Join  (0) 2020.05.27
DB 옵티마이저  (0) 2020.05.27