본문 바로가기

SQL Server 2008

(8)
Foreign Key와 Index 를 Drop & Create 하는 구문 생성하기 요즘은 게임 DB 통합을 준비하고 있답니다. 게임의 장르에 따라 다르겠지만 월드 개념이 있는 경우, 유저의 접속 트래픽에 따라 신규 월드를 오픈하거나 기존의 월드를 합치는 이슈가 발생하는데요. 신규 월드를 오픈하는 것과는 달리 월드를 통합하는 일은 DBA의 역할이 매우 큽니다. 작업의 내용을 한마디로 정의한다면, "완전히 동일한 레이아웃을 가진 두개의 DB를 하나로 합치는 일" 이라고 할 수 있겠군요. 말은 간단하지만 고려해야 할 요소는 조금 있는 편입니다. - PK, UK의 중복 문제 - 데이터 merge 성능 (서비스 다운타임을 줄이기 위한 싸움) - 통합 진행 상황을 모니터할 수 있게끔 단계 별로 로깅 - 각 단계 별 에러 핸들링 오늘 포스팅할 내용은 데이터 merge 성능을 향상 시키기 위해 미리..
SQL Server 2008에서 binary와 string의 상호 변환 SQL 2005에서 binary 0x0123을 string '0x0123'으로 변환하려면 문서화되지 않은 시스템 함수 master.sys.fn_varbintohexstr() 를 사용해야 했습니다. 전 2008에서도 여전히 그 방법을 사용하고 있었는데.. CONVERT() 함수에 해당 기능이 이미 들어가 있었더군요. 심지어 '0x0123'을 0x0123으로 반환할 수도 있습니다. (이래서 what's new는 꼼꼼히 살펴봐야...) binary to string SELECT CONVERT(char(6), 0x0123, 1) SELECT CONVERT(char(4), 0x0123, 2) string to binary SELECT CONVERT(binary(2), '0x0123', 1) SELECT CONVE..
MERGE 응용 - 2. CTE를 사용한 성능 최적화 MERGE 문의 기본 형태 MERGE [타겟 테이블] AS T USING [소스 테이블] AS S ON T.[컬럼] = S.[컬럼] WHEN MATCHED THEN UPDATE SET ~~~ WHEN NOT MATCHED BY TARGET THEN INSERT ~~~ WHEN NOT MATCHED BY SOURCE THEN DELETE; WHEN NOT MATCHED BY SOURCE THEN DELETE; 지난 번에 다룬 UPSERT에 한 가지 동작이 추가되었습니다. 이 동작을 수행하되 타겟 테이블의 일부만 가져와서 MERGE하는 경우를 생각해 봅시다. IF OBJECT_ID(N'dbo.MergeTest', N'U') IS NOT NULL DROP TABLE dbo.MergeTest; GO CREATE..
MERGE 응용 - 1. UPSERT UPSERT ??? 조건을 만족하는 행이 있으면 UPDATE하고, 그렇지 않으면 INSERT하는 구문입니다. 하지만, SQL Server에서는 UPSERT문을 지원하지 않습니다. SQL Server 2008 - MERGE 문 SQL Server 2008에 추가된 MERGE 문을 사용하면 하나의 문에서 여러 INSERT, UPDATE 및 DELETE 작업을 수행할 수 있습니다. 단, MERGE문을 잘 못 작성하면 악성 쿼리로 전락하거나, 예기치 않은 동작으로 데이터의 손실을 유발할 수 있으니 익숙하게 사용할 수 있도록 테스트 구문을 많이 작성해 보시기 바랍니다. MERGE 문으로 UPSERT를 구현 지금까지 SQL Server에서 UPSERT를 수행하려면, UPDATE 후 @@ROWCOUNT를 확인해 다시..
SPARSE 컬럼 테이블에서 NULL 값을 허용하는 컬럼에 사용하는 옵션으로 SPARSE 가 있습니다. [SQL Server 2008] SPARSE 컬럼에 NULL 값이 입력되면 저장 공간을 전혀 차지 하지 않지만, NULL이 아닌 값이 저장될 경우에는 4byte의 추가 공간을 필요로합니다. BOL에서는 SPARSE 컬럼의 사용으로 인해 20% ~ 40% 정도의 공간이 절약될 수 있다면 SPARSE 컬럼을 사용하라고 권고하는군요. 아래 표는 SPARSE 컬럼을 사용했을 때 40%의 공간을 절약하기 위해 필요한 NULL 값 비율을 데이터 타입 별로 나타내고 있습니다. 데이터 타입 NULL 비율 bit 98% tinyint 86% smallint 76% int 64% bigint 52% real 64% float 52% sm..
Change Tracking [SQL Server 2008] 변경이 잦지 않은 대용량 테이블의 데이터 또는 데이터베이스에 비교적 큰 부하가 걸리는 Query의 결과셋을 미들웨어 서버의 메모리에 캐시함으로써, 데이터베이스의 부하를 줄일 수 있습니다. 이런 미들웨어 서버를 만들 때 가장 신경 쓰이는 부분은 "데이터베이스에서 데이터가 변경되었는지 여부를 어떻게 판단할 것인가?" 인데, 보통 이런 방법이 사용됩니다. - 변경이 발생할 때마다 Trigger를 사용하여 별도의 테이블에 변경을 기록한다. 미들웨어 서버는 추가 테이블을 확인. => 개인적으론 잘만든 Trigger는 나쁘게 생각하지 않지만, 그래도 Trigger는 보통 지양되는 경향이 있습니다. 추가 테이블을 사용해야한다는 것도 조금 걸리는 부분. - timestamp열을 추가하고 변경이 발생하면 timestam..
[Sequel Safe] 에러 핸들링 (下) ErrorHandler 레이블 에러 핸들링을 위한 루틴은 아래와 같이 레이블(Label)로 만듭니다. ErrorHandler: IF XACT_STATE() 0 ROLLBACK TRANSACTION; IF @intReturnValue IS NULL OR @intReturnValue = 0 EXEC @intReturnValue = dbo.P_AddErrorLog; RETURN @intReturnValue; ErrorHandler 레이블에서의 프로세스는... 1. 현재 트랜잭션이 열려있으나 commit할 수 없는 상태이면, 트랜잭션을 rollback 한다. 2. @intReturnValue 변수의 값이 NULL이거나 0이면, P_AddErrorLog를 호출하고 해당 SP의 리턴 값을 @intReturnValu..
[Sequel Safe] 에러 핸들링 (上) Stored Procedure에서의 에러 핸들링은 매우 중요한 주제입니다. 따라서, 에러를 핸들링하는 방법은 그 규칙을 정해 모든 개발자가 지키도록 하는 것이 바람직하다고 생각합니다. 에러 핸들링을 아예 하지 않는 것도 좋지 않고, 개발자마다 각자의 방식을 사용하는 것도 좋지 않습니다. 누군가가 이 역할을 맡아 주어야 하는데, DBA가 해주면 좋지만 여건이 되지 않는다면 이 글을 읽고 계신 여러분이 직접 해 보는 건 어떨까요? 에러에는 어떤 종류가 있을까? 간단히 분류해 본다면, 논리적 에러와 시스템 에러가 있습니다. 여기서 시스템 에러를 다시 둘로 나누면, 에러는 다음과 같이 분류할 수 있습니다. 1. 논리적 에러 로직을 처리하는 과정에서 "예외 사항"로 분류하여 실행을 중단하거나 롤백 해야 하는 상황..