87

리팩토링 데이터베이스 : 진화적 데이터베이스 디자인

  • View
    271

  • Download
    22

Embed Size (px)

DESCRIPTION

스캇 W. 앰블러, 프라모드 J. 세달라지 지음 | 정원혁, 이재범, 권태돈, 성대중, 현중균 옮김 | ISBN: 9788995856444 | 25,000원 | 2007년 06월 29일 발행 | 400쪽

Citation preview

Page 1: 리팩토링 데이터베이스 : 진화적 데이터베이스 디자인
Page 2: 리팩토링 데이터베이스 : 진화적 데이터베이스 디자인

리팩토링 데이터베이스에 대한 찬사

"데이터베이스 리팩토링의 새 장을 여는 이 책은 데이터베이스 스키마를 바꾸는 일이 어렵

지 않으며, 데이터를 마이그레이션 하는 일도 부담스러워 할 필요가 없고 또한 데이터베이

스 전문가가 고객과 개발자로부터 받는 변경 요청으로 과중한 부담을 가질 필요가 없다는

사실을 밝혀주고 있다. 진화적인 디자인은 기민함(agility)의 중심에 있다. 앰블러(ambler)

와 세달라지(sadalage)는 애자일 데이터베이스가 서서히 발전하는 방식을 보여준다."

- 조슈아 커리프스키(Joshua Kerievsky), Industrial Logic의 창립자, 패턴을 활용한 리팩토링의 저자

"이 책은 진화적 데이터베이스 개발의 기초를 설계할 뿐 아니라, 데이터베이스 리팩토링의

실용적이고 상세한 많은 예제를 제공한다. 애자일 개발론에 관심이 있는 데이터베이스 직종

의 사람이라면 반드시 읽어야 할 책이다."

- 더그 배리(Doug Barry), Barry & Associates 대표, Web Services and Service-Oriented Architectures: The Savvy Manager’s Guide 저자

"앰블러와 세달라지는 다른 저자들에 의해 매우 어려운 것으로 생각되던 문제에 대한 과감한 접

근을 시작하였다. 그들은 데이터베이스 리팩토링 이면의 이론적인 부분과 함께 실제 적용에 있

어 그 단계적인 과정을 확인되고 성의있는 방법으로 설명하고 있다. 하지만 정말 놀라운 것은

200 페이지가 넘는 예제 코드와 특정 데이터베이스 리팩토링 장애물을 극복할 수 있는 방법을

기술적으로 상세하게 설명한 예시였다. 이 책은 아이디어만 좋은 그럴듯한 또 다른 소개서가 아

니라 개발자와 데이터베이스 관리자 모두 가까이 두고 활용할 수 있는 튜토리얼이자 참고서적

이다. 다른 이들은 시도조차 하지 않은 그 곳에서 용기있는 이 둘의 명성은 계속될 것이다."

- 케빈 아구아노(Kevin Aguanno), 수석 프로젝트 매니저, IBM 캐나다

"실무 프로젝트에 종사하는 사람은 누구나 스콧과 프라모드가 리팩토링 데이터베이스를 가

지고 소프트웨어 개발 생명 주기(software development life cycle)에 가져온 영향을 인

정할 것이다. 기존의 데이터베이스를 다루는것은 현실적으로 쉬운 일이 아니다. 우리가 직

면하는 도전의 대부분은 문화적 차이에서 오는 것일 수 있고, 추진한다 하더라도 DBA의 방

식에 의해 강요되어 불확실한 상태에 놓일 수 있다. 하지만 이 책은 기술적으로 리팩토링과

데이터베이스의 진화적 개발이 어떻게 애자일한 방법으로 처리될 수 있는지를 보여준다. 내

가 만나는 바로 옆의 고지식한 DBA의 책상에 이 책을 놓아두고 싶다."

— 존 컨(Jon Kern)

Page 3: 리팩토링 데이터베이스 : 진화적 데이터베이스 디자인

"이 책은 탁월한 책일 뿐만 아니라 애자일 개발론과 객체 기술(object technology) 분야에

서 결과를 도출해내야 하는 데이터 전문가에게 필요한 내용을 완벽히 담고있다. 리팩토링

데이터베이스가 무엇이고, 어떻게, 왜 일어나는지 보여주는 잘 구조화된 책이다. 나는 데이

터베이스를 개발하고 개선할 때마다 이 책을 마치 최고의 요리책처럼 이용할 생각이다."

- 데이비드 R. 해트즌, 편집자, The Data Management Center , First Place Software, Inc.

"이 훌륭한 책은 리팩토링의 기민한 수행방법을 데이터의 세계로 가져왔다. 조직 내에서

리팩토링 데이터베이스을 할 수 있는 두 방법론에 대한 실용적인 안내와 개별 리팩토링을

어떻게 구현하는지 그 자세한 내용을 제공한다. 또한 리팩토링 데이터베이스는 개발자와

DBA 간의 협력의 중요성을 유기적으로 잘 연관시킨다. 개발자와 DBA모두 마찬가지로 이

책을 반드시 레퍼런스로 가지고 있어야 한다."

- 퍼 크롤(Per Kroll), 개발 매니저, RUP, IBM; project lead, Eclipse Process Framework

"마틴 파울러(Martin Fowler)가 코드 리팩토링에 한 것을 스콧과 프라모드는 데이터베이

스 리팩토링에서 해냈다. 저자는 데이터베이스의 품질을 향상시키는 데 이용할 수 있는 논

리적인 프로시저들을 함께 포함하였다. 여러분이 데이터베이스를 다루고 있다면, 이 책은

당신을 위한 선물이다."

- 켄 퍼그(Ken Pugh), 저자, Prefactoring

"데이터를 다루는 사람들이 애자일 랭크에 참여한 지는 오래된 일이고 앰블러와 세달라지는

그 조직을 선도하는 사람이다. 이 책은 데이터 모델러와 관리자뿐만 아니라 소프트웨어 개

발자들도 꼭 읽어야 한다. 우리는 너무 오랫동안 다른 세계에 살았고, 이 책은 그동안 우리

를 나누고 있던 장애물을 제거하는 데 도움을 준다."

- 게리 K. 에번스, Agile Process evangelist, Evanetics, Inc.

"진화적 디자인과 리팩토링은 이미 흥미있는 주제이고, 리팩토링 데이터베이스와 함께 이것

은 더욱 더 좋아졌다. 이 책에서는 저자가 데이터베이스에서 리팩토링을 하는 기술적, 전략

적인 내용을 함께 설명하고 있다. 리팩토링을 이용하여 데이베이스 스키마는 프로덕션 환경

으로 배포된 이후에도 안전하게 점진적으로 발전될 수 있다. 이 책과 함께라면 어떤 개발자

라도 데이터베이스는 자신의 능력 범위 안에 있게 된다."

- 스밴 고츠(Seven Gorts)

Page 4: 리팩토링 데이터베이스 : 진화적 데이터베이스 디자인

리팩토링 데이터베이스- 진화적 데이터베이스 디자인

스캇 W. 앰블러 (Scott W. Ambler)

프라모드 J. 세달라지 (Pramod J. Sadalge)

Page 5: 리팩토링 데이터베이스 : 진화적 데이터베이스 디자인

스캇:

사랑하는 나의 아내 베벌리에게.

프라모드:

나의 가장 사랑하는 여인 루팔리와 우리 딸 알루라에게.

Page 6: 리팩토링 데이터베이스 : 진화적 데이터베이스 디자인

vi

Page 7: 리팩토링 데이터베이스 : 진화적 데이터베이스 디자인

vii

목 차

목 차

리팩토링 데이터베이스에 대한 찬사 ................................. i

왜 진화적 데이터베이스 개발인가? .................................. xxvii

기민함(Agility)에 대한 요약 ....................................... xxix

이 책을 어떻게 읽을 것인가? ....................................... xxx

1 장 진화적 데이터베이스 개발 2

1.1 데이터베이스 리팩토링 ................................... 5

1.2 진화적 데이터 모델링 ..................................... 5

1.3 데이터베이스 회귀 테스트 ................................. 8

1.4 데이터베이스 아티팩트 형상관리 ........................... 11

1.5 개발자 샌드박스 ......................................... 12

1.6 진화적 데이터베이스 개발 기술의 장애물 .................... 13

1.7 무엇을 배웠나 ........................................... 14

2 장 데이터베이스 리팩토링 16

2.1 코드 리팩토링 ........................................... 16

2.2 데이터베이스 리팩토링 ................................... 18

2.2.1 단일 애플리케이션 데이터베이스 환경 ....................... 20

2.2.2 다중 애플리케이션 데이터베이스 환경 ....................... 22

2.2.3 의미 유지 .............................................. 24

2.3 데이터베이스 리팩토링의 분류 ............................. 27

2.4 데이터베이스 냄새 ....................................... 28

Page 8: 리팩토링 데이터베이스 : 진화적 데이터베이스 디자인

viii

리팩토링 데이터베이스

2.5 어떻게 데이터베이스 리팩토링을 적합하게 할 것인가 .......... 30

2.6 데이터베이스 스키마를 보다 쉽게 리팩토링하기 ............... 32

2.7 무엇을 배웠나 ........................................... 33

3 장 데이터베이스 리팩토링 프로세스 34

3.1 데이터베이스 리팩토링이 적절한지 검증한다 ................. 37

3.2 가장 적절한 데이터베이스 리팩토링을 선택한다. .............. 39

3.3 원본 데이터베이스 스키마는 더 이상 지원되지 않음을 표시한다. . 40

3.4 리팩토링 전, 후는 물론 리팩토링 도중에도 테스트를 한다 ...... 42

3.4.1 데이터베이스 스키마 테스트하기. .......................... 42

3.4.2 데이터 마이그레이션 검증하기. ............................ 45

3.4.3 외부 액세스 프로그램 테스트하기 ........................... 47

3.5 데이터베이스 스키마를 변경한다 ........................... 47

3.6 소스 데이터 마이그레이션(Migration) ...................... 50

3.7 외부 액세스 프로그램을 리팩토링한다 ....................... 51

3.8 회귀 테스트를 실행한다 ................................... 52

3.9 작업한 내용에 대해 버전 관리를 한다. ...................... 53

3.10 리팩토링이 끝났음을 알린다. .............................. 53

3.11 무엇을 배웠나 ........................................... 55

4 장 프로덕션으로 배포하기 56

4.1 샌드박스 사이의 효과적인 배포 ............................ 57

4.2 데이터베이스 리팩토링의 번들화 ........................... 59

4.3 배포 윈도우 스케줄링 ..................................... 61

4.4 시스템 배포 ............................................. 62

4.5 더 이상 지원되지 않는 스키마 제거 ......................... 64

4.6 무엇을 배웠나 ........................................... 65

Page 9: 리팩토링 데이터베이스 : 진화적 데이터베이스 디자인

ix

목 차

5 장 데이터베이스 리팩토링 전략 66

5.1 작은 변경사항이 적용하기 더 쉽다 .......................... 67

5.2 개개의 리팩토링은 유일하게 식별되어야 한다 ................ 67

5.3 여러 개의 작은 변경으로 큰 변화를 구현한다 ................ 69

5.4 데이터베이스 설정 테이블을 유지한다 ...................... 70

5.5 뷰나 배치 작업보다 트리거를 통한 동기화를 사용한다 .......... 70

5.6 충분한 과도기를 가진다 ................................... 71

5.7 데이터베이스 ‘변경 관리 위원회’ 전략을 단순화한다 ........... 72

5.8 다른 팀과의 협의 과정을 단순화한다 ........................ 72

5.9 데이터베이스 접근을 캡슐화한다 ........................... 73

5.10 데이터베이스 환경설정을 쉽게 할 수 있도록 한다.............. 73

5.11 SQL 문장의 중복을 피한다 ............................... 74

5.12 데이터베이스 자산을 형상관리 시스템하에 둔다 ............... 74

5.13 정치를 숙지한다 ......................................... 74

5.14 무엇을 배웠나 ........................................... 75

온라인 리소스 ................................................... 75

6 장 구조적 리팩토링 76

구조적 리팩토링 구현의 일반적인 고려사항 ........................... 77

컬럼 제거(Drop Column) ........................................ 80

테이블 제거(Drop Table) ........................................ 86

뷰 제거(Drop View) ............................................. 88

계산된 컬럼 도입(Introduce Calculated Column) ................. 90

대리 키 도입(Introduce Surrogate Key) ......................... 94

컬럼 병합 (Merge Columns) .................................... 101

테이블 병합(Merge Tables) ..................................... 105

컬럼 옮기기(Move Column) ..................................... 112

Page 10: 리팩토링 데이터베이스 : 진화적 데이터베이스 디자인

x

리팩토링 데이터베이스

컬럼명 바꾸기(Rename Column) ................................. 118

테이블명 바꾸기(Rename Table) ................................. 122

뷰 이름 바꾸기(Rename View) ................................... 127

LOB 형식을 테이블로 대체

(Replace Large Object (LOB) With Table) ........... 130

컬럼 바꾸기(Replace Column)................................... 137

일대다 관계를 연관 테이블로 바꾸기

(Replace One-to-Many With Associative Table) .... 141

대리키를 자연키로 바꾸기

(Replace Surrogate Key With Natural Key) ................... 146

컬럼 분할(Split Column) ........................................ 151

테이블 분할(Split Table) ......................................... 156

7 장 데이터 품질 리팩토링 161

데이터 품질 리팩토링 구현시 일반적인 문제 ........................... 162

룩업 테이블 추가(Add Lookup Table) ............................ 163

표준 코드 적용(Apply Standard Codes) ......................... 167

표준 타입 적용 (Apply Standard Type) .......................... 172

키 통합 전략(Consolidate Key Strategy) ........................ 178

컬럼 제약조건 제거(Drop Column Constraint) .................... 182

기본 값 제거(Drop Default Value) ............................... 184

Not Null 제약조건 제거(Drop Non-Nullable) ..................... 187

컬럼 제약조건 도입(Introduce Column Constraint) ............... 190

일반 형식 도입(Introduce Common Format) ..................... 193

기본 값 도입(Introduce Default Value) .......................... 196

NULL 값을 허용하지 않는 컬럼 만들기

(Make Column Non-Nullable) ........................ 199

데이터 옮기기(Move Data) ....................................... 203

Page 11: 리팩토링 데이터베이스 : 진화적 데이터베이스 디자인

xi

목 차

형식 코드의 속성 플래그화

(Replace Type Code With Property Flags)........... 207

8 장 참조무결성 리팩토링 214

외래키 제약조건 추가(Add Foreign Key Constraint) .............. 215

계산된 컬럼을 위한 트리거 추가

(Add Trigger For Calculated Column) ............... 221

외래키 제약조건 삭제(Drop Foreign Key Constraint) ............. 225

캐스캐이딩 삭제(Cascading Delete) ............................. 227

물리적 삭제(Hard Delete) ....................................... 232

논리적 삭제(Soft Delete) ........................................ 235

이력 데이터를 위한 트리거(Trigger For History) ................... 241

9 장 아키텍처적 리팩토링 245

CRUD 메서드 추가(Add Crud Method) .......................... 246

미러 테이블 추가(Add Mirror Table) ............................. 251

읽기 메서드 추가(Add Read Method) ............................ 256

뷰를 이용한 테이블 캡슐화(Encapsulate Table With View) ......... 259

계산된 메서드 도입(Introduce Calculation Method) .............. 261

인덱스 도입(Introduce Index) ................................... 264

읽기 전용 테이블 도입(Introduce Read-Only Table) ............. 267

데이터베이스에서 마이그레이션 하는 메서드

(Migrate Method From Database) .................... 274

데이터베이스로 마이그레이션하는 메서드

(Migrate Method To Database) ...................... 278

뷰로 메서드 대체(Replace Method(s) With View) ................. 282

메서드로 뷰 대체(Replace View With Method(s)) ................. 285

공식 데이터 소스 사용하기(Use Official Data Source) .............. 288

Page 12: 리팩토링 데이터베이스 : 진화적 데이터베이스 디자인

xii

리팩토링 데이터베이스

10 장 메서드 리팩토링 293

10.1 인터페이스 변경 리팩토링 ................................. 294

10.1.1 매개변수 도입(Add Parameter) ......................... 294

10.1.2 메서드 매개변수화(Parameterize Method) ............... 295

10.1.3 매개변수 제거(Remove Parameter) ..................... 296

10.1.4 메서드 이름변경(Rename Method) ...................... 296

10.1.5 매개변수 순서 변경(Reorder Parameters) ................ 297

10.1.6 매개변수를 명시적 메서드로 바꾸기

(Replace Parameter with Explicit Methods) .......... 299

10.2 내부적인 리팩토링(Internal Refactorings) ................ 300

10.2.1 조건식 통합(Consolidate Conditional Expression) ..... 300

10.2.2 조건절의 분해(Decompose Conditional) ................ 301

10.2.3 메서드 추출(Extract Method) ........................... 302

10.2.4 변수 도입(Introduce Variable) ......................... 305

10.2.5 제어 플래그 제거(Remove Control Flag) ................. 307

10.2.6 중개자 제거(Remove Middle Man) ...................... 308

10.2.7 매개변수 이름 변경(Rename Parameter) ................. 308

10.2.8 리터럴을 참조 테이블로 대체

(Replace Literal with Table Lookup) ................. 308

10.2.9 중첩된 조건절을 단위별 조건절로 대체

(Replace Nested Conditional with Guard Clauses) .. 310

10.2.10 임시 변수 분리(Split Temporary Variable) .............. 311

10.2.11 알고리즘 대체(Substitute Algorithm) .................... 312

11장 변환 313

데이터 추가(Insert Data) ........................................ 314

새로운 컬럼 도입 (Introduce New Column) ....................... 319

새로운 테이블 도입 (Introduce New Table) ....................... 322

뷰 도입(Introduce View) ........................................ 325

데이터 변경 (Update Data) ...................................... 329

Page 13: 리팩토링 데이터베이스 : 진화적 데이터베이스 디자인

xiii

목 차

부록 데이터 모델링을 위한 UML 표시법 334

용어 용어 정리 339

도서 참고 & 추천 도서 345

찾기 찾아 보기 349

Page 14: 리팩토링 데이터베이스 : 진화적 데이터베이스 디자인

xiv

역 자 서 문

마틴 파울러가 소개한 리팩토링을 읽고 나서 기술서적을 통해 받는 감동이 이런 것이구나,

하는 흥분에 한동안 사로잡혀 있던 기억이 있다. 그만큼 오랫동안 올바른 길로 인도해 줄

현자(賢者)의 지혜(智慧)에 목말라 있었고, 리팩토링이 그 갈증을 해소해 주었기 때문일 것

이다. 하지만 이는 코드의 세계에 살고 있는 개발자(Devopler)를 위한 선물이였고, 데이터

베이스를 업으로 살고 있는 나를 포함한 데이터 전문가에게는 여전히 먼 이웃나라의 이야

기일 뿐이었다.

그러던 중 리팩토링 데이터베이스(Refactoring Database, 스콧 엠블러)란 제목의 책을

처음 접하게 되었고 한순간 그 책의 표지를 멍하게 쳐다본 적이 있다. 그 때 내 머리 속에

는 “마침내”라는 단어가 계속 맴돌고 있었다. 그 후 정말로 우연하게 그 책 ‘리팩토링 데이

터베이스’의 번역을 요청받았을 때, 기대와 그에 상반대는 부담감으로 선뜻 결정을 못 내리

고 한동안 망설인 것이 사실이다. 사실 혼자의 힘으로는 감당할 수 없었지만 여러 사람의

노고가 있었기에 지금 이 책이 여러분의 손에 있는 것이다.

어떤 분야의 대가가 쓴 책을 온전히 번역한다는 것이 쉬운 일은 아니었다. 정서와 문화

적 차이가 조금씩 존재하지만 저자의 표현과 말의 뉘앙스를 최대한 여과없이 그대로 전달

하고자 많은 노력을 했다. 역자의 번역서가 아닌 저자의 원서처럼 되기를 희망하지만, 그

부담감은 책이 출판되는 이 시점에도 숨길 수가 없다.

이 책이 데이터베이스 개발에 가져다 줄 그 영향을 생각해 볼 때, 매우 고무적인 일이 아

닐 수 없다. 이전의 잘못된 문화에 대해 개개인이 혼자 고민하며 묵묵히 참고 따라가느라

급급했다면, 이 책은 기존의 경직된 데이터베이스 개발의 변화에 대한 두려움과 망설임에

서 용기와 확신의 땅으로 우리를 인도해 준다.

이 책이 나오기까지 많은 도움을 주신 베타리더 서창희님을 비롯한 위키북스 출판사 직

원 여러분께 진심으로 감사를 드린다. 또한 데이터베이스 분야에서 활발하게 활동하며 좋

Page 15: 리팩토링 데이터베이스 : 진화적 데이터베이스 디자인

xv

역 자 서 문

은 책의 필요성을 공감하고 기꺼이 번역에 참여한 성대중, 권태돈, 현중균 씨에게도 감사

의 말을 전한다. 그리고 주중에는 회사일로, 주말에는 번역일로 정신없이 바빴던 일정을

묵묵히 지켜보고 인내해 준 사랑하는 아내와 아이들에게도 사랑과 감사를 보내고 싶다. 무

엇보다 이 모든 것 위에 계신 하나님께 감사를 드린다.

- 이재범

번역을 한 책이 벌써 10여권이 넘는다. 그럼에도 불구하고, 이번처럼 알차게 번역을 해본

적이 없다. 처음에는 나의 열정이 넘쳤다. 베타리더도 내가 찾아서 부탁을 했었다. 이번에

는 출판사의 열정이 넘친다. 너무 열정이 넘쳐서 이렇게 번역하면 다른 출판사랑 일하는

양의 두 배 이상이구나 싶을 정도다. 그럼에도 이 출판사가 고맙다. 아직까지 살아오면서

이렇게 꼼꼼하게 번역하는 출판사를 접해보지 못했다.

1년 전쯤 이 책을 번역해달라고 들고 왔다. 첫 눈에 Microsoft SQL Server에 관련된 책

이 아니기에 우리 분야가 아니라고 거절했다. 아마 기억에 다시 또 오셨던 듯하다. 일단 책

을 한 권 받았다. 이 분야를 많이 아는 재범씨에게 검토를 해보라고 했다. 보자마자 이 책

너무 좋은 책이라고 한다. 속을 들여다 봤다. 해 볼까? 말까? 그리곤 바빴다. 사실, 잊고

있었다. 다시 또 이야기가 진전이 되고 시작하기로 했다. 그리곤 또 바빴다. 바쁘다는 건

번역보다 더 중요한 다른 일들이 가로 막았다는 의미. 그럼에도 불구하고 위키북스는 오랫

동안 기다려주었다.

그 기다림에 감사해서, 그리고 그 분들의 성의와 진실성을 보고 일을 시작했다. 아무래

도 개발쪽 코드와 용어가 많아서 재범씨가 이 일의 책임을 맡기로 했다. 그리고 번역할 부

분을 나누었다. 정작 다른 분들은 자신의 맡은 부분을 번역했는데, 나만 늦었다. 이 책이

늦게 나오게 된 가장 큰 이유다. 1차 교정, 베타리더 교정, 2차 교정–긴 기간 동안 재범씨

는 책임 맡은 자로서 가장 수고를 많이 했다.

위키북스 직원분들은, 출판사는 편집 잘 하고, 디자인 잘 해서 책 내보내는 것이라는 고

정 관념을 깨주었다. 그간 오간 메일만 해도 350여통이다. 언제 파주에 가서 그곳 구경도

하련다. 일을 하다가 이렇게 성실하게 하는 분들을 보면, 인간적으로도 사귀고 싶은 맘이

드는데 이 분들이 그렇다.

Page 16: 리팩토링 데이터베이스 : 진화적 데이터베이스 디자인

xvi

리팩토링 데이터베이스

함께 했던 태돈, 대중, 중균은 자신의 몫을 잘 감당해주었고, 특히 졸업하고 의욕이 넘치

는 태돈은 자신의 몫뿐 아니라 잡다한 서문과 감사의 글 등 다양한 부분을 ‘자발적으로’ 나

서서 번역해주었다. 이들은 소중한 나의 재산이다.

이 책은 그렇게 나오게 되었다.

책을 내면서 이것도 부족하고 저것도 부족하다는 생각을 많이 해왔지만, 그래도 이 책은

그런 두려움에서 그나마 먼~ 책이다. 미비함이 없다는 것이 아니라 한국의 열악한 출판 상

황에 비추어 보건데 그 상황에서 할 수 있는 최선을 다한 책이라고 스스로 자부한다. 이번

번역을 하면서 또 한번 배움이 늘고, 수준이 업그레이드 되는 경험을 했다.

감사함을 드린다. 기다려 주고, 꼼꼼히 책을 준비한 출판사, 컨설팅과 강의의 본연의 일

을 하며 부가적으로 번역일을 감당했던 동료들, 그리고 역시 가장에게 번역의 시간을 더

할애해준 가족들에게 감사를 드린다. 이를 위해 기도해준 나의 지체들, 특히 도움이 필요

한 곳에 자신이 가진 작은 보리떡과 물고기를 드리기 위해 함께 하는 iT드림팀 지체들의 기

도에 감사를 드린다.

- 정원혁

콜롬버스가 계란을 세운 것을 보고 많은 사람은 그렇게 하면 누가 못 해, 라고 이야기를 했

다. 리팩토링 데이터베이스는 세운 계란에 비유할 수 있다. 데이터베이스를 리팩토링하는

기술적 요소들은 대부분 기존에 존재하는 것들이지만, 이들을 리팩토링에 활용할 줄 아는

생각과 능력은 아무나 가진 것이 아님이 틀림없다. 그렇게 누군가 발상의 전환을 통해 새

로운 생각을 해내기 전까지 우리는 기존 고정관념의 틀에 박혀 살아간다. 데이터베이스에

대한 고정관념도 분명히 존재한다. 스키마 변경 불가론을 목숨처럼 지키며 살아가고 있는

우리. 이런 우리에게 이 책은 스키마의 변경이 얼마나 쉽고 체계적으로 이루어질 수 있는

것인지를 보여준다. 리팩토링 데이터베이스를 통해 우리가 가진 데이터베이스에 대한 고정

관념이 타파될 수 있는 하나의 계기가 되었으면 한다.

- 권태돈

Page 17: 리팩토링 데이터베이스 : 진화적 데이터베이스 디자인

xvii

역 자 서 문

이 책의 번역에 동참하면서 제일 먼저 가졌던 생각은 역시 두려움이다. 가보지 못한 길과

같은 생소한 개념과 어휘와의 만남 속에 당혹감을 감추지 못하며 번역 작업에 발을 디뎠다.

그럼에도 불구하고 조악한 번역을 여러 번의 수정 및 탈고 과정을 통해 바로잡아 준 재범

님과 ‘자발적이지 못한’ 것을 반성하며 심기일전의 계기를 주신 정원혁 상무님께 감사를 드

릴 뿐이다.

날마다 새로운 도전은 계속된다. 그 안에서 살아있는 의미를 찾을 수 있는 열매를 얻게

하시는 전능하신 하나님과 사랑하는 아내에게 다시 한 번 잘 해보리라는 다짐과 사랑의 마

음을 드린다.

- 성대중

다른 분들에 묻어간다, 라고 할까?

번역은 하면 할수록 힘들어지고 그 벽이 높음을 알게 된다.

내 몫을 거의 해준 재범 책임님,

열심히 하는 모습을 보여주는 열정의 대중 책임님,

놀라운 성장의 태돈 주임님,

말없이 모델이 되시는 상무님.

이번에도 사람을 붙여주신 하나님의 사랑을 알게 된다.

그리고, 가족이라는 선물에도 감사함을 전한다.

- 현중균

Page 18: 리팩토링 데이터베이스 : 진화적 데이터베이스 디자인

xviii

정원혁 (주)필라넷 상무이사, SQL Server Academy 본부장,

http://blog.naver.com/wonhyukc

약 2년 전 꿈의 조직, 필라넷(www.feelanet.com) DB사업부를 만들었으며, SQL Server

Academy(www.sqlacademy.com)를 맡고 있다. 한국 내 SQL Server 전문가 그룹인

SQL Specialist의 창립자이며 리더이다. 컨설팅 고객사로는 Yes24, 홍진크라운, 부동산

114, 삼성반도체, AIG, 동양증권, KT 등이 있다.

쉬고플 때 쉬면서 일할 수 있는, 행복할 수 있는 직장을 만들 꿈을 꾸며 살고 있고, 어디

든 도움이 될 곳이 있다면 달려갈 준비를 한발씩 해나가고 있다. 아직도 여전히 하고 싶은

게 너무나 많고, 하나님 이끄시는 대로 살아가려고 노력은 하고 있다. 최근에는 주신 IT 재

능을 사용하여 필요한 사람들에게 도움을 주기 위해 다른 나라에 교육 센터를 세워 후원하

고 있다.

이재범 (주)필라넷 책임 컨설턴트

(주)필라넷에서 Microsoft SQL Server와 관련 개발 부분의 컨설팅을 하고 있으며, 컨설팅

고객사로는 삼성생명, 동양증권, 부산은행, ING생명, 삼성전기, 조선일보, NHN, 호남석

유 등이 있다. 다년간 금융권/제조업 관련 시스템 설계 및 개발을 해왔으며, 현재 데이터베

이스 성능 튜닝뿐만 아니라 애플리케이션 성능 관리와 오픈소스에 분야에 관심이 많다.

첫 돌을 맞은 한 아이를 둔 가장으로 그 아이의 이름처럼 하나님의 평안을 바라며 살고자

노력하고 있다.

역 자 소 개

Page 19: 리팩토링 데이터베이스 : 진화적 데이터베이스 디자인

xix

역 자 소 개

권태돈 (주)필라넷 주임 컨설턴트

(주)필라넷에서 Microsoft SQL Server 관련 컨설팅(BI 및 Analysis Service 분야를 담당)

을 하고 있으며 컨설팅 업무와 병행하여 트라이콤 교육센터, 삼성멀티캠퍼스 등에서 SQL

Server 과정 전문강사와 SQLMania.net 운영자로 활동하고 있다. 과거 학사 관련 시스템

개발과 주요 메이저 음반사 시스템 개발을 주로 담당했다.

지금은 데이터베이스에 많은 비전을 가지고 필라넷에 입사하였고, 최근 컨설팅 고객사로

는 한국투자증권, 부동산114, YES24 등이 있다. 관심분야로는 데이터베이스 마케팅, 경영

정보 시스템, BI이다.

성대중 (주)필라넷 책임 컨설턴트

(주)필라넷에서 Microsoft SQL Server 관련 컨설팅을 하고 있으며, 최근 컨설팅 고객사로

는 YES24, AIG, 미래에셋생명, 부동산 114, CyberMBA, 삼성반도체 등이 있다.

한국 내 SQL Server 전문가 그룹인 SQL Specialist와 .NET Advisor SQL 그룹의 멤

버로 활동하고 있으며, MSDN, TechNET 아티클에 대한 번역과 SQL Server 관련 도서의

번역 프로젝트에 참여하고 있다.

관심분야는 Tuning과 ERP 컨설팅 부분이며, 주경야경을 불사하는 바쁜 일정 중에서도

주일과 수요일에는 교회에 나가야 하는 평범한 크리스챤이다.

현중균 (주)필라넷 차장

(주)필라넷 DB사업부에서 Presale를 주로 하고 있으며, 최근 컨설팅 고객사로는 YES24,

AIG, 부동산 114, CyberMBA, CDI홀딩스 등이 있다.

현재는 SQL Server Reporting Service와 SQL Server 관련 솔루션에 대해 관심이 많

으며 이들을 통한 원가 절감에 초점을 맞추고 있다.

2005년 SQL Server 매거진 전문 번역을 했으며 네이버에 SQL 관련 사이트를 운영중에

있다. 관심분야는 Reporting Service와 부서 마케팅, 코칭이다.

Page 20: 리팩토링 데이터베이스 : 진화적 데이터베이스 디자인

xx

스캇 W. 앰블러(Scott W. Ambler)는 토론토 북쪽에 살고 있는 소프트웨어 프로세스

임프루브먼트(software process improvement)사의 컨설턴트이다. 그는 애자일 모델

링(Agile Modeling, www.agilernodeling.corn), 애자일 데이터(Agile Data, www.

agiledata.org), 엔터프라이즈 통합 프로세스(Enterprise Unified Process, www.

enterpriseunifiedprocess.com), 애자일 통합 프로세스(Agile Unified Process, www.

ambysoft.com/unifiedprocess)의 설립자이자 프랙티스 리더이다. 그는 애자일 모델

링(Agile Modeling: John Wiley & Sons, 2002), 애자일 데이터베이스 테크닉(Agile

Database Techniques: John Wiley & Sons, 2003), 오브젝트 프리머(The Object

Primer 3판: Cambridge University Press, 2004), 엔터프라이즈 통합 프로세스(The

Enterprise Unified Process: Prentice Hall, 2005), The Elements of UML 2.0

Style(Cambridge University Press, 2005)과 같은 많은 책을 (공동) 집필하였다. 그는

Software Development 매거진(www.sdmagazine.com)의 편집자로 활동을 하고 있

으며, Software Development, UML World, Object Expo, Java Expo, Application

Development와 같은 다양한 국제 컨퍼런스에서 기조 연설자로 활약하고 있다. 스캇은 토

론토대학교에서 정보과학 석사학위를 취득하였다. 남는 시간에는 가라데 스타일의 공수도

(Goju Ryu)와 고무도(Kobudo)를 연마한다.

프라모드 J. 세달라지(Pramod J. Sadalage)는 엔터프라이즈 응용 프로그램 개발 통합 회

사인 ThoughtWorks에서 컨설턴트로 일하고 있다. 그는 1999년부터 익스트림 프로그래

밍(Extreme Programming)을 적용하여 대규모의 J2EE 응용 프로그램을 개발하고 있는

진화적 데이터베이스 디자인과 데이터베이스 리팩토링의 선구자이다. 그는 일찍이 많은 프

로젝트에 자신만의 방법과 프로세스를 적용해 보았다. 또한 진화적 프로젝트(데이터베이스

에 진화적 프로세스를 적용하는 것)를 바탕으로 모든 사람들이 진화적 디자인을 데이터베

이스에 쉽게 적용할 수 있도록 데이터베이스 관리에 관한 책을 쓰고 강연을 했다. 일하지

않을 때는, 부인과 딸과 함께 달리기를 하며 시간을 보낸다.

저 자 소 개

Page 21: 리팩토링 데이터베이스 : 진화적 데이터베이스 디자인

xxi

10년 전 리팩토링이라는 말은 대개 스몰토크(Smalltalk) 커뮤니티와 같은 일부 사람들에

게만 알려져 있었다. 갈수록 많은 사람들이 훈련된 효율적인 방법으로 리팩토링을 적용하

여, 운영중인 코드를 수정해 나가는 것을 보면 놀라운 것이 사실이다. 그 결과 많은 사람들

이 소프트웨어 개발에서 코드 리팩토링을 필수적인 과정으로 생각하게 되었다.

나는 엔터프라이즈 응용 프로그램의 세계에서 일하고 있으며 엔터프라이즈 응용 프로그

램의 많은 부분은 데이터베이스와 함께 동작한다. 내가 쓴 리팩토링에 관한 원래 책에서

데이터베이스 리팩토링은 새로운 문제로 등장하고 있기 때문에 리팩토링에 있어서 데이터

베이스는 중요한 문제영역이라고 지적하였다. 이러한 문제들은 데이터베이스 전문가와 소

프트웨어 개발자 사이에서 불신과 몰(沒)이해로 인한 단절된 벽으로 말미암아 생긴 엔터프

라이즈 소프트웨어 세계의 슬픈 영역이다.

스캇(Sccot)과 프라모드(Pramod)에 관해 내가 좋아하는 한 가지는 앞서 설명한 두 영역

을 넘나들며 서로 다른 방법으로 열심히 일하고 있다는 것이다. 스캇은 두 영역간의 갈라

진 틈을 잇는 가교 역할을 하는 데이터베이스 코드를 작성하고 있으며, 그의 객체 관계형

매핑(object-relational mapping)에 대한 성과물은 나의 엔터프라이즈 애플리케이션 아

키텍쳐에 많은 영향을 미쳤다. 프라모드는 덜 알려졌을지 모르나, 그가 나에게 준 충격은

실로 대단했다. 그와 함께 ThoughtWork사에서 일할 때, 우리는 데이터베이스 리팩토링

은 불가능하다고 이야기를 했다. 하지만 프라모드는 이러한 기존의 생각을 거부하고 개략

적인 아이디어와 함께 데이터베이스 스키마를 일관되게 유지할 수 있으면서 변경 가능하거

나 제어할 수 있는 프로그램의 원리에 대해 연구했다. 이것은 소프트웨어 개발의 영역에서

코드로부터 시작하여 진화적인 디자인을 사용할 수 있게끔 해주었다. 프라모드는 우리의

많은 고객들과 ThoughtWorks 직원에게 이러한 테크닉을 적용하여 끊임없이 일어나는 데

이터베이스 디자인에 대한 장애물을 영영 떨쳐버리게 하였다.

이 책은 응용 프로그램과 데이터 사이에 적당한 다리가 없는 곳에 살았던 두 사람의 교훈

추 천 사

Page 22: 리팩토링 데이터베이스 : 진화적 데이터베이스 디자인

xxii

리팩토링 데이터베이스

을 정리하여 데이터베이스를 위한 리팩토링 테크닉을 소개한다. 이미 리팩토링 경험을 가

지고 있다면, 다른 것과 비교했을 때 주요한 차이점은 단지 응용 프로그램과 데이터 구조

를 변경하는 것뿐만 아니라 데이터 자체의 연속적인 이관을 관리하는 점이라는 것을 알게

될 것이다. 이 책은 이러한 일을 어떻게 하는지를 알려주고, 이러한 두 가지 내용을 바탕으

로 프로젝트 진행을 도와준다.

나는 이 책이 출판돼 정말 기뻤다. 하지만 이것은 첫 단계라고 생각한다. 리팩토링에 대

한 책을 출판한 뒤에 나는 자동으로 리팩토링 작업을 해주는 정교한 도구를 찾을 수 있어

기뻤다. 나는 데이터베이스에도 똑같은 일이 일어나고 스키마와 데이터의 연속적인 이관

을 모든 사람들이 쉽게 할 수 있도록 해주는 도구를 만드는 회사가 나타나길 바란다. 그러

한 일이 일어나기 전에 이 책은 여러분만의 프로세스와 도구를 만드는 데 도움이 될 것이다.

나중에 이 책은 리팩토링 도구의 사용에 있어 기초적인 정보를 제공함으로 인해 영속적인

가치를 가지게 될 것이다.

- 마틴 파울러(Martin Fowler), series editor; chief scientist, ThoughtWorks

내가 소트프웨어 개발 부문에서 처음 일할 때와 비교하면, 사회와 기술의 많은 부분들이

역동적으로 변하였다. 그러나 변하지 않은 것은 소프트웨어 개발의 근본적인 성질이다. 컴

퓨터를 가지고 코드를 대량 생산하는 소프트웨어를 만드는 것은 어려운 일이 아니다. 하지

만 좋은(good) 소프트웨어를 만드는 일은 어렵고, 훌륭한(great) 소프트웨어를 만드는 일

은 더욱 더 어렵다. 이러한 상황은 오늘날에도 변하지 않았다. 오늘날에는 많은 소스 코드

를 참조할 수 있고, 발전된 소프트웨어 개발 도구를 가졌고, 소프트웨어 개발 과정에서 무

엇이 동작하고 동작하지 않음을 예전보다 잘 알게 되었다. 그리고 이러한 것들로 인해 이

전과 비교하여 더 크고 복잡한 소프트웨어 시스템을 만들 수 있게 되었다. 하지만 아직도

대부분의 소프트웨어는 불안정하고 수용 가능한 품질 수준을 맞추기 위해 애쓰고 있다. 아

마도 이것은 우리가 더 크고 복잡한 소프트웨어를 만들면서 비롯되었거나 아직도 사용되고

있는 기술이 가진 근본적인 문제점에서 발생했을 수도 있다. 나는 오늘날 소프트웨어 개발

이 이러한 두 가지 요소로 인해 아직 도전할 만한 것이라고 믿는다. 다행스러운 것은, 새로

운 기술과 테크닉이 나타나 이따금 우리에게 도움을 준다는 것이다. 이러한 발전들 사이에

서, 대부분의 프로젝트를 시작하는 시점에 아주 작은 것이 우리에게 자신의 잠재성을 깨닫

Page 23: 리팩토링 데이터베이스 : 진화적 데이터베이스 디자인

xxiii

추 천 사

고 증진시키는 힘을 길러준다. 애자일 방법론(Agile methodologies)과 함께 연관지어 생

각할 때, 리팩토링과 관련이 있는 기술은 이러한 몇 안 되는 발전 사항이다. 이 책에서 포

함하고 있는 내용은 이러한 기초 원리를 매우 중요한 방향으로 확장하고 있다.

리팩토링은 행위 의미론(behavioral semantics)의 변경 없이(즉 외부 동작은 변경 없

이) 안전한 방법으로 코드 디자인을 향상시키는 정형화된 기술이다. 누구나 노력만 한다면

코드를 향상시킬 수 있는 기회가 있다. 리팩토링은 안전하게 변화를 일으키고, 리팩토링을

통해 소프트웨어 개발 커뮤니티에 의해 축적된 지식을 사용할 수 있게 한다. 파울러가 쓴

이러한 주제에 대한 책으로 인해, 리팩토링이 광범위하게 적용되었고, 리팩토링 대상의 검

출을 도와주는 소프트웨어 도구와 더불어 코드에 적용되는 리팩토링 애플리케이션으로 인

해 더 활발히 진행되었다. 그러나 응용 프로그램의 데이터 티어(data tier)에서 리팩토링의

적용은 많이 힘들다는 것이 입증되었다. 이 책에서 보여주듯이 이러한 문제는 의심할 여지

가 없으며, 또한 데이터 티어에 적용할 수 있는 명확한 리팩토링이 존재하지 않는다. 데이

터 레벨에서 잘못된 디자인은 그보다 높은 티어에 문제를 항상 전이하기 때문에 참으로 안

타까운 일이다. 더욱이, 데이터 티어를 발전시킬 수 있는 능력이 없는 것은(변화를 거부하

거나 두려워하든지에 관계 없이) 최고의 소프트웨어가 탄생하는 것을 방해한다. 이러한 문

제들은 리팩토링을 통해 하는 일이 얼마나 중요한지 보여준다.

나는 이 책의 출판을 보고 매우 흥분하였다. 그리고 이 책에서 설명한 내용의 테크닉을

구현한 도구의 탄생을 기대하게 되었다. 소프트웨어 산업은 오픈 소스 소프트웨어의 성장

과 협동 작업이 가져올 영향력 때문에 현재 흥미로운 단계에 있다. 데이터베이스 리팩토링

에 관심이 있는 사람에게 Eclipse Data Tools Platform과 같은 프로젝트는 자연스러운 협

동 작업 사례로 손꼽힌다. 잠재적인 이익이 엄청나기 때문에 오픈 소스 커뮤니티가 이러한

비전에 동참하여 더욱 더 열심히 노력해 주길 기대한다.

-존 그레이엄(John Graham), Eclipse Data Tools Platform, Project Management, committee chair, senior staff

engineer, Sybase, Inc.

여러 면에서 데이터 커뮤니티는 전체 애자일 소프트웨어 개발 진영의 진화를 간과했다. 소

프트웨어 개발자가 리팩토링과 테스트 주도 개발을 비롯해 다른 테크닉들을 수용하는 동안

데이터 전문가들은 이러한 것들을 무시하고 트랜드에서 벗어나기에 이르렀다.

Page 24: 리팩토링 데이터베이스 : 진화적 데이터베이스 디자인

xxiv

리팩토링 데이터베이스

이러한 일은 내가 경력이 얼마 되지 않은 상태에서 큰 금융 서비스 회사의 응용 프로그램

개발자로 일할 때 분명히 다가왔다. 그 당시 나는 개발팀과 데이터베이스 팀 사이의 작은

방에 위치하고 있었다. 내가 그곳에 있었을 때 바로 느낄 수 있었던 것은 두 팀은 얼마 떨

어져 있지 않지만 문화, 관행, 일 처리 과정에 있어서 너무나 다르다는 것이었다. 고객의

요구사항은 개발팀에게는 리팩토링과 코드 체크인, 적극적으로 수용 가능한 테스트를 의미

한다. 비슷한 요청이 데이터베이스 팀에게는, 스키마의 변경이 있기 전에 많은 단계의 전

형적인 요청 절차를 밟는 것을 의미한다. 이러한 과정은 개발자와 고객 모두를 불편한 관

계 속에 두게 되지만 데이터베이스 팀은 다른 방법이 없다는 것을 알기 때문에 이것이 계

속된다.

그러나 요즘과 같은 무한 경쟁 시대에서 살아남기 위해서는 반드시 자신이 해오던 방식

과는 다른 식의 방법을 배워야만 한다. 데이터 커뮤니티는 어떻게 해서라도 소프트웨어 개

발자에 상응할 수 있는 애자일 테크닉을 수용해야 한다.

데이터베이스 리팩토링은 데이터 전문가들이 앞으로 얼마나 도약할 수 있는지, 그리고

확신 있고 안전한 방법으로 어떻게 변화를 수용할 수 있는지를 보여주는 매우 귀중한 자원

이다. 스캇과 프라모드는 작은 단계에서부터 시작하여, 반복적으로 일을 진행하면서 큰 실

수를 범하는 것을 피하고, 데이터베이스 스키마를 고객의 요청에 따라 조금씩 발전시켜 나

가는 것을 보여준다.

실수 없이 데이터베이스를 리팩토링하기란 어려운 일이다. 비록 컬럼의 이름을 바꾸는

간단한 변화라도 스키마와 그 객체, 데이터베이스 계층 프레임워크, 응용 프로그램계층에

문제를 전파해서, DBA로 하여금 이것이 매우 까다로운 테크닉이라 생각되게 만든다.

데이터베이스 리팩토링은 전문 DBA가 애자일 방법론을 데이터베이스 디자인과 개발 과

정에 어떻게 적용하는지를 보여주는 규범적인 훈련에 대한 윤곽을 말한다. 스캇과 프라모

드의 관심은 데이터베이스 리팩토링의 광범위한 수용을 위한 방법에 있다. 게다가 나는 모

든 데이터 전문가들에게 이를 행동에 옮길 것을 제안하였다. 읽고, 변화를 수용하고, 내용

을 알려라. 데이터베이스 리팩토링은 데이터 커뮤니티의 기민함을 증진시키는 중요 요소가

될 것이다.

-사 친 레키(Sa chin Rekhi), program manager, Microsoft Corporation

Page 25: 리팩토링 데이터베이스 : 진화적 데이터베이스 디자인

xxv

추 천 사

시스템 개발의 세계에서, 구별되는 두 종류의 문화가 있다. 객체 지향성(OO, object-

oriendted)에 사로잡혀 사는 자바와 애자일 소프트웨어 개발자, 그리고 조심성 있는 처리

와 튼튼한 관계형 데이터베이스 디자인을 음미하는 사람들로 구성된 관계형 데이터베이스

세계가 있다. 이 두 그룹의 사람들은 서로 다른 언어를 사용하고, 서로 다른 협회에 참석하

고, 서로 다른 말을 하는 것처럼 보인다. 이런 분파는 많은 조직의 IT 부서 안에서 재현된

다. 객체지향개발자는 DBA와 대화가 잘 되지 않고, 빠른 속도의 변화가 불가능하다고 불

평한다. 데이터베이스 전문가들은 데이터베이스에 대해 전혀 이해를 못하는 자바 개발자들

을 가엽게 여긴다.

스캇 앰블러와 프라모드 세달라지는 두 세계에 중립적인 몇 안 되는 사람들의 그룹에 속

해 있다. ‘리팩토링 데이터베이스: 진화적 데이터베이스 디자인’은 객체지향 아키텍쳐적인

시각에서 쓰여졌다. 결과적으로 이 책은 객체지향 개발자와 관계형 데이터베이스 전문가

모두에게 가치 있는 정보를 제공한다. 객체지향 개발자에게는 데이터베이스에 애자일 코드

리팩토링 테크닉을 적용하고 관계형 데이터베이스 전문가들에게는 객체지향 아키텍쳐들이

어떻게 생각하는지 통찰할 수 있는 기회를 준다.

이 책은 데이터베이스 디자인의 질을 향상시킬 수 있는 많은 팁과 테크닉을 포함하고 있

다. 이미 데이터베이스가 존재하고 있으나 디자인이 엉성하게 돼 있거나, 초기 데이터베이

스 디자인이 그다지 좋은 모델을 생성하지 못한 상황과 같이 실제 현업에서 생각할 수 있

는 방법에 초점에 맞추고 있다.

이 책은 다양한 수준의 사람이 볼 수 있도록 되어 있다. 첫째, 개발자를 위한 적절한 가

이드를 제시한다. 또 이 책은 객체지향 개발자와 관계형 데이터베이스 전문가들의 생각을

적절히 조화시킬 수 있는 방법을 소개한, 시사하는 바가 큰 전문서적이다. 나는 데이터베

이스가 클래스를 영구적으로 복사해 놓은 것 이상의 의미를 가진다는 앰블러와 세달라지의

함축된 주장이, 지금보다 많은 시스템 아키텍트들의 반향을 불러 일으켰으면 한다.

-Dr. 폴 도시(Paul Dorsey), president, Dulcian, Inc.; president, New York Oracle Users Group; chairperson,

J2EE SIG

Page 26: 리팩토링 데이터베이스 : 진화적 데이터베이스 디자인

xxvi

Extreme Programming (XP), Serum, the Rational Unified Process (RUP), the

Agile Unified Process (AUP), Feature-Driven Development (FDD)와 같은 진화적(때

론 애자일) 소프트웨어 개발 방법론은 과거 몇 년 사이에 폭풍이 불 듯 IT 산업에서 수용

되었다. 정의 그 자체가 말 해 주듯이, 진화적인 방법은 반복적이며 자연 증가하는 형태이

며, 애자일 방법은 이 진화적 방법을 이용한 고도의 협업 방법이다. 리팩토링, 짝 프로그램

(pair programming), 테스트 주도 개발(test-driven development), 애자일 모델 주도

개발(Agile ModelDriven Development)과 같은 애자일 테크닉은 IT 조직의 진보를 이루

어 냈다. 이러한 방법과 테크닉은 상아탑 안에서 고안된 것이 아니라 일반 대중 사이에서

수년에 걸쳐 개발되어 발전하였다. 한마디로 말하면, 이러한 진화와 애자일의 소산은 놀라

울 정도로 잘 동작한다.

리팩토링에 대한 기초가 된 책에서 마틴 파울러는 리팩토링을 코드의 행위적 의미는 변

경하지 않고 그 디자인을 향상 시킬 수 있는 소스 코드의 작은 변화라고 설명하고 있다. 다

른 말로는, 아무것도 망치거나 더하지 않고 지금의 작업 내용의 품질을 향상시킬 수 있다

는 것이다. 이 책에서 마틴은 응용 프로그램의 소스 코드를 리팩토링하고, 데이터베이스

스키마를 리팩토링할 수 있는 아이디어를 설명한다. 그러나 데이터베이스 리팩토링은 데이

터베이스 사이의 높은 수준의 결합도로 인하여 매우 어려운 일이라고 지적하고, 그러한 내

용은 그의 책에서 제외되었다.

리팩토링이 발행된 1999년부터 우리 둘은 데이터베이스 스키마를 리팩토링 하는 방법을

찾기 시작했다. 처음 우리는 Software Development(www.sdexpo.com)와 같은 컨퍼런

스나 메일링 리스트(www.agiledata.org/feedback.html)를 통해 따로 작업을 시작하였다.

각자의 생각을 이야기하고 컨퍼런스 자료를 검토한 결과, 겹치는 부분이 있고 공존할 수

있는 내용임을 알았다. 그래서 우리는 이 책을 쓰고 리팩토링을 통해 데이터베이스 스키마

를 증진시킬 수 있는 경험과 테크닉을 공유하기로 의견을 모았다.

서 문

Page 27: 리팩토링 데이터베이스 : 진화적 데이터베이스 디자인

xxvii

서 문

이 책에 나와있는 예제들은 Java, Hibernate, Oracle을 통해 작성되었다. 사실상 모든

데이터베이스 리팩토링 예제는 데이터베이스 스키마 자체를 변경하는 코드를 포함하고 있

으며, 우리는 이 책에서 좀 더 흥미로운 리팩토링을 위해 Java 응용 프로그램의 소스 코드

에 미치는 영향을 보여준다. 또 모든 데이터베이스가 모두 비슷하게 만들어진 것이 아니라

서, 구현에 있어서 데이터베이스 제품 간의 미묘한 차이를 설명함과 동시에 또 다른 전략

도 함께 설명하고 있다. 몇 가지 리팩토링의 구현은 SET UNUSED이나 RENAME TO 명령과

같은 Oracle에 특화된 특성을 이용하였고, 많은 예제 코드에서 Oracle의 COMMENT ON

명령을 이용하였다. 다른 데이터베이스 제품도 데이터베이스 리팩토링을 보다 쉽게 만드는

요소를 포함하고 있고, 훌륭한 DBA는 이러한 장점을 어떻게 수용해야 하는지 알 것이다.

미래의 데이터베이스 리팩토링 도구는 우리에게 훨씬 쉽게 이러한 일들을 가능하게 해줄

것이다. 이 책은 또한 Java 소스 코드만을 포함하고 있는데, 이를 C#, C++, VisualBasic

과 같은 다른 언어로 변환할 수 있으리라 믿는다.

왜 진화적 데이터베이스 개발인가?

진화적 데이터베이스 개발은 이제부터 빛을 발할 개념이다. 데이터베이스 스키마를 프로젝

트 초기 단계에서 확정하는 대신, 프로젝트 기간 내내 책임자에 의해 정의된 변경 요구사

항을 반영할 수 있도록 만든다. 좋아하든 좋아하지 않든 간에, 프로젝트를 진행하면서 요

구사항은 변하게 마련이다. 전통적인 접근법은 이러한 현실을 부정하고 다양한 수단을 동

원하여 변화가 일어나지 않도록 완곡한 방법으로 관리하는 것이었다. 현대의 개발 테크닉

을 사용하는 사람들은 지금 필요로 하는 기술과 관련하여, 일을 한 단계 발전시킬 수 있는

것을 선택해야 한다. 그러한 측면에서 프로그래머는 TDD, 리팩토링, AMDD와 이러한 작

업을 쉽게 해주는 새로운 개발용 도구를 수용해야 한다. 이렇게 한 뒤에 진화적 데이터베

이스 개발을 위한 테크닉과 도구가 또한 필요함을 깨달았다.

데이터베이스 개발에 있어 진화적 접근법이 갖는 장점은 다음과 같다.

1. 허비되는 시간을 줄여준다. JIT(Just-in-time) 접근법은 요구 사항이 변화되었을 때,

어쩔 수 없이 발생하는 일련의 소모성 시간을 피할 수 있게 해 준다. 초기의 요구

사항, 아키텍쳐, 디자인 구조는 시간이 흐른 뒤에 요구 사항이 더 이상 필요하지 않

Page 28: 리팩토링 데이터베이스 : 진화적 데이터베이스 디자인

xxviii

리팩토링 데이터베이스

게 되면 없어진다. 이미 어떤 일을 최고로 할 수 있는 기술을 가졌다면, 같은 일을

JIT를 통해 할 수 있는 능력 또한 갖추어야 한다.

2. 큰 재작업을 피하게 한다. 1장 ‘진화적 데이터베이스 개발’에서 볼 수 있듯이, 앞으로

발생할지도 모르는 중요한 이슈들을 고려해서 초기 모델링 작업을 해야 할 필요가

있다. 이러한 잠재적인 이슈들을 프로젝트에서 늦게 발견하면 심각한 재작업을 초

래할 수도 있기 때문이다. 그렇다고 초기 프로젝트 작업부터 너무 상세한 내용을 조

사할 필요는 없다.

3. 시스템의 동작 상태를 항상 파악하게 된다. 진화적 접근을 통해 비록 데모 환경으로 배

포된다 할지라도 정기적으로 운영 소프트웨어를 만들어라. 매주 혹은 두 주마다 새

로운 운영 소프트웨어를 만들면, 프로젝트의 위험도는 매우 효과적으로 줄어든다.

4. 지금 사용하는 있는 데이터베이스 설계가 가능한 최고의 품질인지를 파악할 수 있다. 이것이

바로 데이터베이스 리팩토링을 의미한다. 즉 여러분의 스키마 설계를 조금씩 향상

시켜 나가는 것이다.

5. 소프트웨어 개발자와 뜻이 맞는 방법으로 일할 수 있다. 소프트웨어 개발자가 진화적인

방법으로 일하고 있고, 데이터 전문가가 현대적인 개발 팀의 영향력 있는 일원이 되

길 원한다면, 두 사람은 또한 진화적인 방법을 선택할 필요가 있다.

6. 전체에 걸친 작업을 줄인다. 진화적인 방법으로 일함으로써, 지금 필요한 일만 하고 그

이상의 일은 하지 않는다.

진화적 데이터베이스 개발의 몇 가지 단점은 다음과 같다.

1. 문화적 장애물이 존재한다. 많은 데이터 전문가들은 프로그래밍이 시작되기 전에 논리

적으로 구체화된 폼과 물리적 데이터 모델이 생성되어야 한다는 소프트웨어 개발에

있어서의 순차적인 접근방법을 선호할지 모른다. 이러한 방법은 너무 비효율적이고

위험하기 때문에 현대적인 방법론을 거부한 데이터 전문가들이 할 일을 없게 만든

다. 더욱 안타까운 것은, 데이터 커뮤니티 내의 많은 사고의 리더(thought leaders)들은

70~80년대 사람으로 90년대의 객체 진화(object revolution)를 만나지 못 하였기 때문

에 진화적인 개발 경험을 습득하지 못 한 사람들이다. 세상은 변하였지만 그들은 아

직도 변해 보이지 않는다. 이 책을 통해 배울 수 있듯이 모든 데이터 전문가들이 진

화적인 방법으로 일할 수 있는 것은 아니며, 사실 애자일 방법론을 사용하지 않는다

면 일하기가 더 편할 수도 있다.

Page 29: 리팩토링 데이터베이스 : 진화적 데이터베이스 디자인

xxix

서 문

2. 유연한 태도를 가져라. 이러한 새로운 테크닉을 배우는 데는 시간이 걸리고, 모든 작

업이 순차적으로 일어나야 한다는 마인드를 진화적인 태도로 바꾸는 데는 훨씬 많

은 시간이 걸릴 수 있다.

3. 도움을 주는 도구는 아직도 발전중이다. 1999년에 리팩토링에 관한 책이 발간되었을 때

리팩토링을 지원하는 도구는 없었다. 몇 년이 지난 지금, 모든 단일 통합 개발 환경

(IDE, Integrated Development Environment)은 코드 리팩토링 기능을 내장하고

있다. 현재 이 글을 쓰고 있는 시점에서 데이터베이스 리팩토링 도구는 존재하지 않

지만 수작업을 통해 리팩토링을 구현할 수 있는 모든 코드를 이 책에 포함하고 있다.

운 좋게 Eclipse Data Tools Project (DTP)는 Eclipse 내에 데이터베이스 리팩토

링 기능을 개발할 것을 그들의 프로젝트 설명서에서 알리고 있어 소프트웨어 밴더

들이 이러한 도구를 내놓는 것은 시간문제라고 본다.

기민함(Agility)에 대한 요약

이 책이 애자일 소프트웨어 개발에 대해 한정지어 이야기하는 책은 아니지만, 데이터베이

스 리팩토링은 애자일 개발에 있어 주요한 테크닉이다. Agile Alliance (www.agilealliance.org)

의 네 가지 항목과 일치하게 된다면 그 프로세스는 애자일로 간주된다. 이 항목은 차선이

아닌 우선을 정의하고 있으며, 특정 영역에 한정하여 집중하되 다른 것을 제거하지 않는다.

달리 말하자면, 좌측 개념의 가치도 중요하지만, 우측 개념의 가치는 더욱 중요하다는 것

이다. 예를 들어 프로세스와 도구도 중요하지만 개인(individual)과 상호작용(interaction)이 더

중요하다. 네 가지 애자일 항목은 다음과 같다.

1. 프로세스와 도구보다 개인과 상호작용. 고려해야 할 가장 중요한 요소는 사람, 그리고

그들이 어떻게 함께 일하느냐이다. 이러한 항목을 갖추지 못 할 경우, 최고의 도구

와 프로세스라고 할지라도 무용지물이 되고 만다.

2. 광범위한 문서화보다 동작하는 소프트웨어. 소프트웨어의 개발에 있어 주된 목표는 책임

자의 요청을 모두 충족시킬 수 있고 동작하는 소프트웨어를 만드는 것이다. 그렇다고

하더라도 여전히 문서화 작업은 올바르게 쓰여져야 하고, 시스템이 왜, 어떻게 만들

어졌고, 시스템과 어떻게 동작하는지를 설명하는 역할을 그대로 가지고 있어야 한다.

Page 30: 리팩토링 데이터베이스 : 진화적 데이터베이스 디자인

xxx

리팩토링 데이터베이스

3. 계약 협상보다 고객과의 협업. 고객이 원하는 바를 이야기 해줄 수만 있으면 된다. 하

지만 불행히도 그들은 정확한 시스템의 내용을 요구할 수 있는 능력이 부족할 뿐만

아니라 시간이 지남에 따라 마음을 바꿀 가능성이 있다. 고객과의 계약은 물론 중요

하지만, 계약이 효과적인 의사소통을 대신할 순 없다. 성공적인 IT 전문가들은 그

들의 고객과 긴밀하게 일하며, 고객의 필요가 무엇인지 연구하고, 그들의 고객이 올

바른 선택을 할 수 있도록 도와준다.

4. 계획대로 진행하기보다 변화에 반응을 보임. 일이 진행되면서 프로젝트 이해 관계자는

변화가 필요한 내용과 비즈니스 환경의 변화, 기본적인 기술의 변화를 이해해야 한

다. 변화는 소프트웨어 개발의 현실이고, 결과적으로 프로젝트 계획과 접근법에서

는 변화되는 환경을 염두하고 이를 반영해야 한다.

이 책을 어떻게 읽을 것인가?

이 책의 중요 내용은, 각각의 리팩토링 상세 내역을 설명하는 6장에서 11장의 내용이다. 처

음 5장까지는 진화적 데이터베이스 개발에 대한 기초적인 내용과 테크닉을 다루고, 부분적

으로 데이터베이스 리팩토링에 대한 내용도 포함한다. 반드시 각 장을 순서대로 읽어야 한다.

▒ 1장 '진화적 데이터베이스 개발', 진화적 개발과 이를 지원하는 테크닉의 기초적인 내용

을 다룬다. 데이터베이스 리팩토링, 데이터베이스 회귀 테스트, AMDD 접근을 통

한 진화적 데이터 모델, 데이터베이스 자산 관리 시스템, 분리된 개발 샌드박스의

필요성에 대한 요약으로 이루어져 있다.

▒ 2장 '데이터베이스 리팩토링', 데이터베이스 리팩토링에 대한 보다 심층적인 내용과,

왜 이것의 적용이 힘든지 설명하고 있다. 단순한 단일 애플리케이션 환경뿐만 아니

라 다중 애플리케이션 환경의 복잡한 데이터베이스 리팩토링을 예제로 보여준다.

▒ 3장 '데이터베이스 리팩토링 프로세스', 단순하거나 복잡한 환경의 데이터베이스 스키마

를 리팩토링하는 보다 자세한 내용을 다룬다. 다중 애플리케이션 환경에서는 이전

과 새 버전의 스키마 모두를 데이터베이스에서 지원하기 위해 이 둘이 동시에 존재

하는 과도기(Transition Period)를 가져야 하고, 소프트웨어 팀에서는 프로그램 코

드를 업데이트해서 프로덕션 환경으로 배포하도록 해야한다.

Page 31: 리팩토링 데이터베이스 : 진화적 데이터베이스 디자인

xxxi

서 문

▒ 4장 '프로덕션으로 배포하기', 데이터베이스 리팩토링의 결과를 프로덕션 환경으로 배

포하는 과정을 설명한다. 다수의 팀으로부터 발생한 변화가 통합되고 테스트되어야

하기 때문에 다중 애플리케이션 환경에서 이것은 간단하지 않은 일이다.

▒ 5장 '데이터베이스 리팩토링 전략', 수년에 걸쳐 찾아낸 데이터베이스 스키마 리팩토링

에 대한 최고의 방법을 요약하였다. 또한 아직까지 사용 가능하진 않지만 실험적으

로 시도해 볼 만한 두 가지 아이디어를 포함하고 있다.

Page 32: 리팩토링 데이터베이스 : 진화적 데이터베이스 디자인

xxxii

마틴 파울러 Signature Series의 각 책은 책 표지에 다리 그림을 싣고 있다. 이 전통은 마

틴의 아내가 토목 공학 기술자라는 사실을 반영한다. 이 책을 쓰기 시작했을 때, 마틴의 아

내는 다리나 터널과 같은 수평적인 프로젝트에서 일하기 시작했다. 이 다리는 남부 온타리

오의 Burlington Bay James N. Allan Skyway이며, 해밀턴 항구의 입구를 가로지른다.

여기에는 모두 세 개의 다리가 있다. 두 개의 다리는 그림에 있고, 그림에 없는 세 번째 다

리는 Eastport Drive lift bridge이다.

다리는 두 가지 이유로 중요한 역할을 차지한다. 가장 중요한 것은 지속적인 발전으로 교

통량을 감당한다는 것이다. 다리는 태생적으로 그 지역의 교통을 처리하며, 이것은 1952년

어떤 한 배에 충돌되어 무너진 후 다시 만들어졌을지라도 변함이 없다. 첫 번째 Skywas의

확장 공사는 1958년에 있었고, 손상된 다리를 대신하여 철강 보조물의 도움을 받게 되었다.

Skyway는 토론토와 북쪽, 나이아가라 폭포와 남쪽을 연결하는 주요한 통로였기에 교통량

은 금새 한계에 도달했다. 결국 두 번째 확장을 하게 되었는데, 이번에는 철강의 도움없이

진행되어, 1985년에 완공되었고, 늘어난 교통량을 감당하게 되었다. 점차적으로 진행된 확

장은 토목 공학에서도, 소프트웨어 개발에서도 좋은 경제적 가치를 보여준다.

이 사진을 사용하는 두 번째 이유는 스캇이 온타리오 벌링턴에서 자랐기 때문이다. 사실

그는 요셉 브랜트 병원에서 태어났고, 이 병원은 Skyway 북쪽 근처에 있다. 스캇은 이 사

진을 Nikon D70S로 찍었다.

표 지 에 대 해

Page 33: 리팩토링 데이터베이스 : 진화적 데이터베이스 디자인

xxxiii

다음 사람들에게 이 책에 대한 감사를 드리고자 한다: Doug Barry, Gary Evans,

Martin Fowler, Bernard Goodwin, Joshua Graham, Sven Gorts, David Hay, David

Haertzen, Michelle Housely, Sriram Narayan, Paul Petralia, Sachin Rekhi, Andy

Slocum, Brian Smith, Michael Thurston, Michael Vizdos, Greg Warren.

또 Pramod는 Irfan Shah, Narayan Raman, Anishek Agarwal, 그리고 지속적으로

내 의견에 도전을 던져 주었고, 소프트웨어 개발에 대해 가르쳐준 우리 팀 동료들에게 감

사하고 싶다. Martin에게 감사하고 싶다. 그는 나로 하여금 글을 쓰도록 해주었고, 함께

이야기 하고, ThoughtWorks 밖에서 적극적으로 일하게 허락해 주었다. Kent Beck은 나

에게 격려를 주었다. ThoughtWorks의 동료들은 수많은 방법으로 즐겁게 일할 수 있게 해

주었다. 나를 키우느라 애쓰신 나의 부모님 Jinappa와 Shobha께 감사드린다. 어렸을 때

부터 내 글을 비평하고, 발전시키는 데 도움을 준 내 동생 Praveen에게도 고마움을 전한다.

감 사 의 말

Page 34: 리팩토링 데이터베이스 : 진화적 데이터베이스 디자인

2

1 장 진화적 데이터베이스 개발

"폭포는 관광객들에게 훌륭한 볼거리다. 하지만 폭포수 모델(Waterfall Model)1은 소프

트웨어 개발 프로젝트를 진행하는 데 있어 구경거리라 할 만한 형편없는 전략이다."

–스콧 엠블러

반복적이고 점진적으로 개발을 수행하는 데 필요한 현대의 소프트웨어 프로세스 또는 방

법론이라 부르는 것은 사실상 모두 진화적이다. 예를 들어 RUP(Rational Unified Process)2,

XP(Extreme Programming)3, 스크럼(Scrum), 동적 시스템 개발 방법론(DSDM), 크리스탈 패밀리,

팀 소프트웨어 프로세스(TSP), AUP(Agile Unified Process), EUP(Enterprise Unified Process), 기능

주도 개발(FDD), 그리고 RAD(Rapid Application Development)4 등과 같은 프로세스가 이에 해당

한다. 반복적으로 수행한다는 것은 모델링이나 테스팅, 코딩, 또는 개발을 동시에 조금씩

진행하고 나서 다른 것을 조금, 그리고 또 다른 것을 조금씩 하는 식의 진행을 말한다. 이

러한 프로세스는 구현해야 할 모든 요구사항을 먼저 정의하고 난 후에, 그에 따른 상세 설

계를 만들고, 그러고 나서 해당 설계를 구현하여 테스트하고 최종적으로 시스템을 배포하

는 순차적인 접근방법론과는 조금 다르다.

1.  폭포수 모델(Waterfall model): 전통적인 소프트웨어 개발 모델로, 각 단계를 확실히 매듭짓고 다음 단계로 넘어가는 개발 방법론. 그

모양이 한번 떨어지면 거슬러 올라갈 수 없는 폭포수와 같다고 해서 이름 붙여짐.

2. RUP(Rational Unified Process): 원래는 Rational 사(지금은 IBM으로 합병)의 객체지향 방법론.

3. XP(Extreme Programming): 켄트 벡, 론 제프리 등에 의해 제안된 애자일 방법론 중 하나.

4. RAD(Rapid Application Development): 반복적이고 점진적인 개발 방법론으로 폭포수 모델과 대조적임.

Page 35: 리팩토링 데이터베이스 : 진화적 데이터베이스 디자인

3

1_ 진화적 데이터베이스 개발

점진적인 접근방법에서는 한 번에 대규모로 배포하기보다는 일련의 작은 배포로써 시스

템을 구축해간다. 더욱이, 오늘날 대부분의 프로세스들은 단순하면서도 사실상 진화적이

고 고도의 협업성을 모두 가진 애자일 프로세스이다. 팀이 협업적인 접근법을 취하게 되

면, 팀원들은 효과적으로 함께 작업할 방법을 열심히 찾을 것이다. 이때 비즈니스 고객 같

은 프로젝트 이해 관계자들을 프로젝트의 실제 멤버가 될 수 있도록 반드시 확인해야 한다.

코번(Cockburn 2002)은 상황에 적절히 적용할 수 있는 최신의 의사소통 기법을 도입하는 데

노력을 아끼지 말라고 조언한다. 즉 전화통화보다는 화이트보드 주위에 모여 얼굴을 맞대

고 대화하는 것이 좋고, 누구에게 전자우편을 보내기에 앞서 전화를 걸고, 상세한 문서를

전달할 때에는 이메일을 사용하는 것이 좋다고 말한다. 소프트웨어 개발팀 내에서 보다 나

은 의사소통과 협업은 프로젝트를 성공적으로 이끄는 핵심 열쇠이다.

진화적인 것과 애자일한 방법 모두가 개발 분야에서는 손쉽게 도입되었지만 데이터 분야

에서는 그렇다고 말할 수가 없다. 소프트웨어 구현을 시작하기에 앞서 상당히 상세한 수준

의 데이터 모델이 필요한데, 이들 대부분의 데이터 지향적 기술은 사실상 순차적이다. 더 나

쁜 것은, 이러한 모델이 종종 베이스라인이 되며, 변경을 최소화하기 위해 변경 관리 제어

시스템하에 둔다는 것이다(최종 결과를 고려해 본다면, 이것은 실제 변경 방지 프로세스라

불러야 한다). 문제는 여기에 있다.5 다시 말해, 일반적인 데이터베이스 개발 기술은 현대의

소프트웨어 개발 프로세스의 현실을 반영하지 않는다. 이런 식으로 할 필요가 없는 것이다.

우리의 전제조건은 데이터 전문가들이 이러한 개발자들과 마찬가지로 진화적인 기술을

도입할 필요가 있다는 것이다. 설령 개발자들도 데이터 분야 내에서는 유효성이 입증된 전

통적인 접근방법론으로 돌아가야 한다고 주장하더라도, 전통적인 방법이 늘 제대로 수행되

고 있지는 않다는 사실이 점점 더 분명하게 나타나고 있다. 5장 애자일과 반복적인 개발에

서 크래이그 라만(Craig Larman, 2004)은 정보 기술(IT) 분야를 선도하는 리더들 사이에서 압

도적으로 지지받는 진화적 접근 방법과 그 연구 결과를 제시하고 있다. 결론은 개발분야에

서 널리 사용되고 있는 진화적이고 애자일한 기술이 데이터 분야에서 일반적으로 사용되

고 있는 전통적인 기술보다 더 좋다는 것이다.

데이터 전문가들이 그렇게 하겠다고 선택만 한다면 그들의 작업 전 영역에 걸처 이러한

진화적인 접근방법론을 도입하는 것이 가능하다. 그 첫 번째 단계는 IT 프로젝트 팀의 요

5. Therein lies the rub: 세익스피어의 햄릿에서 인용한 문구

Page 36: 리팩토링 데이터베이스 : 진화적 데이터베이스 디자인

4

Evolutionary Database Development _1

구사항을 반영할 수 있도록 여러분의 IT 조직의 ‘데이터 문화’를 다시 생각하는 것이다. ‘애

자일 데이터(AD) 방법론’(The Agile Data method, 엠블러 2003)에서는 현대의 데이터 지향 활동에

대한 일련의 원칙과 역할을 정확하게 설명하고 있다. 그 원칙은 데이터를 비즈니스 소프트

웨어의 많은 중요한 관점 중 하나로서 어떻게 반영할 것인가 하는 것이며, 개발자는 데이

터 기술에 더욱 적응해야 할 필요가 있다는 것과 데이터 전문가 또한 현대의 개발 테크닉

과 기법을 배워야 할 필요성이 있음을 내포한다. AD 방법론을 사용함으로써, 각 프로젝트

팀은 그 프로젝트 상황에 맞는 고유한 프로세스에 따라야 할 필요가 있다는 것을 인식하게

된다. 현재의 프로젝트가 다루는 엔터프라이즈 이슈 그 이상을 바라보는 중요성 또한 강조

되며 이와 같은 것은 애자일 방법론을 수행하여 프로젝트 팀과 함께 작업하기에 충분한 유

연성을 가지려는 데이터베이스 운영 관리자와 데이터 아키텍트 같은 엔터프라이즈 전문가

에게 필요하다.

두 번째 단계는 진화적인 방법으로 작업을 가능케 하는 새로운 기술을 도입하려는 데이

터 전문가를 위한 것으로, 특히 데이터베이스 관리자가 이에 해당한다. 1장에서는 이들 핵

심 기술을 간단히 소개할 것이지만, 이 책에서 초점을 두고 있는 가장 중요한 기술은 데이

터베이스 리팩토링이다. 진화적인 데이터베이스 개발 기술은 다음과 같다:

1. 데이터베이스 리팩토링. 기존의 데이터베이스 스키마를 한 번에 조금씩 작게 발전시

켜 나가는 것으로 스키마 자체의 의미는 변경하지 않고 그 디자인의 질을 개선한다.

2. 진화적 데이터 모델링. 시스템의 데이터 관점을 반복적이고 점진적으로 모델링하는

것으로 다른 모든 시스템 관점과 마찬가지로 데이터베이스 스키마와 애플리케이션

코드를 함께 서서히 발전시켜 나간다.

3. 데이터베이스 회귀(regression) 테스트. 데이터베이스 스키마가 실제로 수행되는지 확인

한다.

4. 데이터베이스 가공품(artifacts)의 형상관리. 데이터 모델, 데이터베이스 테스트, 테스트

데이터 등이 중요한 프로젝트 가공품으로서 다른 어느 가공품과 마찬가지로 관리되

어야 한다.

5. 개발자 샌드박스. 개발자는 그들 자체적으로 수행할 테스트 환경이 필요하다. 이 환

경에서 구축한 시스템의 일부를 변경하기도 하고, 같은 팀사람들과 통합 작업을 하

기 전에 테스트를 수행하기도 한다.

Page 37: 리팩토링 데이터베이스 : 진화적 데이터베이스 디자인

5

1_ 진화적 데이터베이스 개발

각각의 진화적 데이터베이스 기술을 자세하게 살펴보기로 하자

1.1 데이터베이스 리팩토링

리팩토링(마틴 파울러 1999)은 소스코드를 조금씩 변경하는 것으로 그 디자인을 개선하고 그렇

게 함으로써 기존보다 쉽게 작업할 수 있도록 하는 훈련된 방법이다. 리팩토링의 핵심적인

관점은 소스코드의 행위적 의미를 유지하는 것이다6-리팩토링 시 소스코드의 어떠한 추

가나 삭제도 없다. 다만 그 질을 향상시킨다. 리팩토링 예는 getPersons() 오퍼레이션을

getPeople()로 이름을 변경하는 것이다. 이런 리팩토링을 구현하려면 오퍼레이션의 정의

를 수정하고 나서, 애플리케이션 코드 전체에 걸쳐 이 오퍼레이션의 모든 호출을 변경하여

야 한다. 리팩토링은 코드가 수정 전처럼 아무 문제 없이 다시 실행될 때까지는 끝난 것이

아니다.

이와 비슷하게, 데이터베이스 리팩토링은 데이터베이스 스키마를 간단히 변경하여 그 디

자인을 개선하되, 그것의 행위와 정보의 의미는 모두 원래대로 유지하는 것이다. 테이블과

뷰 정의 같은 데이터베이스 스키마의 구조적 관점이나, 저장 프로시저와 트리거 같은 함

수적 관점 중 하나를 리팩토링할 수 있다. 데이터베이스 스키마를 리팩토링할 때는 스키마

자체를 뜯어 고쳐야 할 뿐만 아니라, 해당 스키마에 종속성을 가진(커플링된) 비지니스 애

플리케이션이나 데이터 추출 같은 애플리케이션 또한 재작성되어야 한다. 데이터베이스 리

팩토링은 코드 리팩토링보다 그 구현이 훨씬 더 어렵기에 매우 신중해야 한다. 데이터베이

스 리팩토링은 2장에서 자세하게 설명하며, 3장에서는 데이터베이스 리팩토링을 수행하는

프로세스에 대해 설명한다.

1.2 진화적 데이터 모델링

이전에 뭐라고 들었든 상관없이, 진화적이고 애자일한 기술은 단순한 “일단 짜보고 고치기

(code-and-fix)7

”의 새로운 이름이 아니다. 여전히 시스템을 구축하기 이전에 요구사항을 찾

아내야 하고 아키텍처와 디자인을 처음부터 끝까지 깊이 생각해야 한다. 그리고 이렇게 하

6. 다시 말하면, 겉으로 보이는 동작의 변화없이 내부 구조를 변경한다

7.  code-and-fix: 이러한 개발 방식은 계획 수립과 분석, 설계의 상위 과정을 무시하고 오로지 코딩(프로그래밍)만을 강조하는, 빨리 일

정을 끝내려는 변형된 무리한 속성 과정

Page 38: 리팩토링 데이터베이스 : 진화적 데이터베이스 디자인

6

Evolutionary Database Development _1

는 한 가지 좋은 방법은 코딩하기 전에 먼저 모델링을 하는 것이다. 그림 1.1은 애자일 모

델 주도 개발(AMDD) (엠블러 2004; 엠블러 2002)에 대한 생명주기를 리뷰한 것이다. AMDD를

사용하면 프로젝트 시작 시점에서 상위 레벨의 초기 모델링을 만든다. 이 모델을 사용하

여 해결하고자 하는 문제 도메인의 전체적인 범위 개요를 나타내고, 구축할 잠재적인 아키

텍처를 모델링한다. 전형적으로 생성하는 모델 중 하나는 ‘슬림(slim)’ 개념적/도메인 모델로

주 비즈니스 엔터티와 엔터티 사이의 관계(relationship)를 그린 것이다.(파울러와 세달라지 2003).

그림 1.2는 금융기관의 간단한 예를 그린 것이다. 이 예제에 프로젝트의 시작 시점에 필요

한 모든 것을 상세하게 선보였다. 목표는 프로젝트 초기에 전체의 주요 이슈를 생각하는

것이다. 당장은 상세화할 필요성이 없는 것에 시간을 쓰지 말고 JIT(Just-in-time) 기반으로

나중에 필요할 때 상세화한다.

주기 n: 개발

주기 2: 개발

주기 1: 개발

주기 0: 초기 모델링

초기 요구사항모델링(일)

초기 아키텍처모델링(일)

모델 스토밍(분)

구현(이상적으로는 테스트 주도 개발)

(시간)

리뷰(선택적)

모든 주기(시간)

그림1.1 애자일 모델 주도 개발(AMDD) 생명주기

Page 39: 리팩토링 데이터베이스 : 진화적 데이터베이스 디자인

7

1_ 진화적 데이터베이스 개발

그림1.2 UML을 사용한 가상 금융기관의 개념적/도메인 모델

기업고객

계좌 <<

도메인 모델 >

>

고객

소유하다

1..*

1..*

보험증권

위치

지점

키오스크

직원

금융기관

자동차

보험

손해보험

생명보험

은행계좌

위탁계좌

~에서

근무하다

0..* 1

손해배상

0..*

1대비하다

Page 40: 리팩토링 데이터베이스 : 진화적 데이터베이스 디자인

8

Evolutionary Database Development _1

개념적 모델은 도메인이 점차 커지는 것을 이해함으로써 자연스럽게 점점 발전되지만,

상세 레벨은 동일하게 남겨둔다. 상세화는 객체모델(소스코드가 된다)과 물리적 데이터 모

델 내에서 파악된다. 이러한 모델은 개념적 도메인 모델에 의해 이끌리며, 그리고 일관성

을 보장하는 다른 아티팩트8와 함께 동시에 개발된다. 그림 1.3은 세 번째 개발 주기의 끝

단계에서 모델의 범위를 표현한 상세 물리적 데이터 모델(PDM)을 그린 것이다. 만약 ‘주

기 0’ 단계가 1 주일이 걸렸다면, 전형적인 프로젝트 기간은 1년 이하이고 개발 주기는 2주

정도다. 이 PDM은 프로젝트 7주 후에 작성한 것이다. PDM은 이 지점에 오기까지의 프로

젝트의 데이터 요구사항과 어떠한 레거시 제약조건이라도 반영한다. 미래의 개발 주기에

대한 데이터 요구사항은 JIT에 근거하여 이 주기동안 모델된다. 진화적 데이터베이스 모

델링은 쉽지 않다. 레거시 데이터 제약조건을 고려해야 할 필요가 있으며, 모두 알고 있듯

이 부주의하고 쓸모없는 소프트웨어 개발 프로젝트가 만든 레거시 데이터 소스는 종종 매

우 지저분하다. 다행히도 훌륭한 데이터 전문가가 원래의 데이터 소스의 뉘앙스를 이해해

서 순차적 접근방법론에 기초를 둔 것처럼 쉽게 JIT에 근거하여 적용할 수 있도록 하였다.

애자일 모델링의 모델링 표준 적용 수행 지침처럼 여전히 인텔리전트 데이터 모델링 규칙

을 적용할 필요가 있다. 진화적/애자일 데이터 모델링의 상세한 예제는 www.agiledata.

org/essays/agileDataModeling.html에 있다.

1.3 데이터베이스 회귀 테스트

기존의 소프트웨어를 안전하게 수정하기 위해 리팩토링을 하거나 새로운 기능을 추가하는

경우, 어떤 부분을 수정한 후에도 잘못된 점이 없다는 사실을 확인할 필요가 있다. 다시 말

하자면, 시스템상에서 회귀 테스트를 수행할 수 있어야 한다는 것이다. 수정후 뭔가 잘못

된 점을 발견했다면, 그것을 고치든지 아니면 변경사항을 다시 되돌려야 한다. 개발자들

사이에서 회귀테스트는 점점 일반적인 일이 되어 가고 있다. 그 이유는 프로그래머들이 코

드와 단위 테스트 슈트를 동시에 개발하기 위해서이기도 하고, 사실상 애자일리스트들은

실제 코드를 작성하기 전에 테스트 코드를 먼저 사용하는 것을 선호하기 때문이다. 단지

애플리케이션 소스 코드를 테스트하는 것처럼 데이터베이스를 테스트하면 안 되는 것인가?

8.  Artifact: 시스템을 개발, 운영또는 지원하는 동안 만들어지고, 변경되는 문서나, 모델, 파일, 다이어그램(diagram) 또는 관련된 다양한

산출물들

Page 41: 리팩토링 데이터베이스 : 진화적 데이터베이스 디자인

9

1_ 진화적 데이터베이스 개발

중요한 비즈니스 로직은 저장 프로시저 형태나, 데이터 검증규칙, 참조무결성(RI) 규칙을

따라 데이터베이스 내에서 구현되고, 명확한 테스트를 거쳐야 한다

그림1.3 UML을 사용한 상세 물리적 데이터 모델링

Cus

tom

erA

ccou

nt

Insu

ranc

ePol

icy

Cus

tom

erID

: big

int <

<PK

>>Ti

tle: v

arch

ar(4

)Fi

rstN

ame:

var

char

(30)

Mid

dleN

ame:

var

char

(30)

Sur

nam

e: v

arch

ar(3

0)P

hone

Num

ber:

varc

har(

15)

Cre

atio

nDat

e: d

ate

Con

curr

ency

Mar

k: in

t

Acc

ount

ID: b

igin

t <<P

K>>

Acc

ount

Type

Cod

e: in

t <<F

K>>

Bal

ance

: cur

renc

yC

reat

ionD

ate:

dat

eC

oncu

rren

cyM

ark:

int

Pol

icyI

D: b

igin

t <<P

K>>

Pay

men

t: cu

rren

cyVa

lue:

cur

renc

yP

aym

entP

erio

d: in

tIn

cept

ionD

ate:

dat

eC

reat

ionD

ate:

dat

eC

oncu

rren

cyM

ark:

int

Cus

tom

erA

ccou

nt<<

Ass

ocia

tive

Tabl

e>>

Acc

ount

ID: b

igin

t <<P

K>>

Cus

tom

erID

: big

int <

<PK

>>H

asW

ithdr

awal

: boo

lean

Has

Che

ckin

g: b

oole

anC

oncu

rren

cyM

ark:

int

Acc

ount

Type

Acc

ount

Type

Cod

e: in

t <<P

K>>

Des

crip

tion:

var

char

(40)

Con

curr

ency

Mar

k: in

t

Cus

tom

erIn

sura

nceP

olic

y<<

Ass

ocia

tive

Tabl

e>>

Pol

icyI

D: b

igin

t <<P

K>>

Cus

tom

erID

: big

int <

<PK

>>Is

Pol

icyH

olde

r: bo

olea

nIs

Pay

ee: b

oole

anC

oncu

rren

cyM

ark:

int

1 10.

.*0..*

1..*

1 11.

.*

1

0..*

desc

ribes

<< 물리적 데이터 모델 >

>

Page 42: 리팩토링 데이터베이스 : 진화적 데이터베이스 디자인

10

Evolutionary Database Development _1

그림1.4 개발을 위한 테스트 우선 접근 방법

흔히 테스트 우선 프로그래밍(Test-First Programming)이라고도 하는 테스트 우선 개발(TFD)

은 개발 방법에 있어 진화적인 접근방법이다. 새로운 코드를 작성하기 전에 먼저 실패할

테스트 코드를 작성해야만 한다. 그림 1.4의 UML 액티비티 다이어그램에 나타난 바와 같

이, TFD의 단계는 다음과 같다.

1. 빠르게 테스트를 추가하라. 지금은 테스트가 실패할 것이므로 기본적으로 테스트하

기에 충분한 코드면 된다.

테스트 추가한다

테스트를 실행한다

조금 수정한다

테스트를 실행한다

[실패]

[실패]

[통과]

[개발 종료]

[계속적인 개발]

0321293533EvolutionaryDevelopmentTDD.eps

11/29/05Carlisle Publishing Services

Page 43: 리팩토링 데이터베이스 : 진화적 데이터베이스 디자인

11

1_ 진화적 데이터베이스 개발

2. 테스트를 실행하라. 단지 빠른 속도를 위해 종종 완전한 테스트 슈트가 단지 일부

분만 실행된다 하더라도 새로운 테스트가 사실상 실패한다는 것을 확인하기 위해서

테스트를 실행하라.

3. 새로운 테스트를 통과하기 위해 코드를 업데이트하라.

4. 테스트를 다시 실행하라. 만약 테스트가 실패했을 경우, 단계3으로 되돌아간다. 그

렇지 않으면, 처음부터 다시 시작한다.

TFD의 가장 좋은 점은 기능을 구현하기 전에 그 기능에 대해 충분히 생각할 수 있게 해

준다는 것이다(여러분은 효과적으로 상세 설계를 하고 있다). 또한 여러분의 작업물을 언

제라도 검증할 수 있는 테스트 코드가 존재한다는 것을 보증하며 그것이 시스템을 변화시

킬 수 있는 용기를 준다. 왜냐하면 누구나 자신이 변경한 결과로 인해 무언가 ‘잘못되었다’

면 이를 강하게 거부할 수 있기 때문이다. 단지 애플리케이션 소스 코드의 완전한 회귀 테

스트를 수행할 때 코드 리팩토링이 가능한 것과 마찬가지로, 데이터베이스를 위한 완전한

회귀 테스트는 데이터베이스 리팩토링을 원활하게 한다(메스자로스 2006).

테스트 주도 개발(TDD) (아스텔스 2003; 벡 2003)은 TFD와 리팩토링이 결합된 것이다. 먼저

TFD 접근법에 따라 코드를 작성하고, 그 후에 실행한다. 필요에 따라 리팩토링에 의한 높

은 수준의 설계가 가능하다는 것을 확인할 수 있다. 리팩토링을 할 때, 하나라도 잘못된 것

이 없는지 확인하기 위해 회귀테스트를 반복해서 진행해야 한다.

이것은 여러 가지의 단위 테스팅 툴을 필요로 하게 될 것이라는 사실을 의미한다. 데이

터베이스를 위한 적어도 하나 이상의 툴과, 각각의 프로그래밍 언어를 위해 외부 프로그램

에서 사용되는 하나 이상의 툴이 필요하게 될 것이다. XUnit 툴은(자바의 Junit, 비주얼베

이직의 VBUnit, 닷넷을 위한 Nunit, 그리고 오라클의 Ounit등) 다행히도 무료이며, 서로

간에 유사성을 가지고 있다.

1.4 데이터베이스 아티팩트 형상관리

때때로 시스템 변경이 나쁜 아이디어였음이 입증된다면, 변경하기 이전의 상태로 되돌릴

필요가 있다. 예로 Customer.Fname 컬럼을 Customer.Firstname으로 이름을 변경하는

것이 50개의 외부 프로그램을 중단시킬지도 모른다면 이 프로그램의 업데이트 비용은 지

Page 44: 리팩토링 데이터베이스 : 진화적 데이터베이스 디자인

12

Evolutionary Database Development _1

금으로선 매우 높은 것이다. 데이터베이스 리팩토링을 가능케 하려면 형상관리 제어 시스

템 하에 다음의 항목들을 저장할 필요가 있다:

▒ 데이터베이스 스키마를 생성할 데이터 정의 언어(DDL) 스크립트

▒ 데이터 적재/ 추출/ 마이그레이션 스크립트

▒ 데이터 모델 파일

▒ ORM(Object/relational mapping) 메타 데이터

▒ 참조 데이터

▒ 저장프로시저 및 트리거 정의서

▒ 뷰 정의서

▒ 참조무결성 제약조건

▒ 시퀀스, 인덱스등과 같은 기타 데이터베이스 개체

▒ 테스트 데이터

▒ 테스트 데이터 생성 스크립트

▒ 테스트 스크립트

1.5 개발자 샌드박스

‘샌드박스’는 시스템이 구축, 테스트 및(또는) 실행되는 완전한 개발환경이다. 안전성의 이

유로 다양한 샌드박스를 분리해서 유지해야 한다. 즉 개발자가 다른 사람의 노력의 결실에

손실을 줄 수 있다는 두려움을 가지지 않도록 자신만의 샌드박스에서 작업하는 것이 가능

해야만 한다. 품질보증 및 테스트 그룹도 개발자가 그들의 소스 데이터와(또는) 시스템 기

능에 오류를 줄 수 있다는 것에 대한 걱정없이 안전하게 시스템 통합 테스트를 수행할 수

있어야 한다. 그림 1.5는 샌드박스의 논리적 구성을 그린 것이다. 이는 논리적인 것이며 실

제로 규모가 크고 복잡한 환경은 아마도 7~8개의 물리적 샌드박스를 가질 것이고, 반면

규모가 작고/단순한 환경에서는 2~3개의 물리적 샌드박스를 가질 것이다. 데이터베이스

스키마를 성공적으로 리팩토링하기 위해서 개발자는 소스 코드를 복사하고 작업할 데이터

Page 45: 리팩토링 데이터베이스 : 진화적 데이터베이스 디자인

13

1_ 진화적 데이터베이스 개발

베이스를 복사하여 점진적으로 발전시켜 나갈 자신만의 물리적 샌드박스를 가질 필요가 있

다. 자신만의 개발 환경을 가짐으로써 안전하게 변경을 수행할 수 있고, 테스트하고 테스

트한 것 중 하나를 취하거나, 버릴수 있다. 데이터베이스 리팩토링이 눈에 보일만큼 만족

스럽다면 공유 프로젝트 환경으로 승급시켜 테스트하고, 형상관리 제어 시스템하에 저장함

으로써 나머지 팀이 전달받게 된다. 결국, 팀은 모든 데이터베이스 리팩토링을 포함한 그

들의 작업을 어떤 데모 및(또는) 프로덕션 테스팅 환경으로 승급시킨다. 이러한 승급은 보

통 개발 주기에서 한 번 발생한다. 하지만 환경에 따라서는 종종 일어나기도 한다.(더 자주

시스템을 승급시키는 것은 가치 있는 피드백을 얻을 수 있는 좋은 기회이다.) 마지막으로,

시스템의 수용과 시스템 테스트가 통과한 후에는 프로덕션에 배포가 된다. 4장 ‘프로덕션

으로 배포하기’에서는 좀 더 자세하게 이러한 승급/배포 프로세스에 대해서 다룬다.

그림1.5 개발자에게 안전성을 제공하는 논리적 샌드박스

개발샌드박스

프로젝트 통합 샌드박스

사전프로덕션 테스트/QA 샌드박스

프로덕션

매우 반복적인 개발

프로젝트 수준 테스트

시스템 수용테스트

운영 및 지원

자주 일어나는

배포

통제된

배포

매우 통제된

배포

빌드

오류버그

리포트소프트웨어 문제

리포트(SPR)

데모 샌드박스

Page 46: 리팩토링 데이터베이스 : 진화적 데이터베이스 디자인

14

Evolutionary Database Development _1

1.6 진화적 데이터베이스 개발 기술의 장애물

이 책에 언급한 기술들을 도입하는 데 따르는 일반적인 장애물을 논하지 않는다면 태만이

나 마찬가지다. 그 첫 번째 장애물로 가장 극복하기 어려운 것이 바로 문화다. 오늘날의 데

이터 전문가 대부분은 ‘일단 짜보고 고치기(code-and-fix)’ 접근론을 개발에 일반적으로 사용

했던 때인 1970년대와 1980년대 초에 경력을 쌓기 시작했다. IT 분야는 이 접근론이 질이

낮고, 코드를 유지보수하기 어렵게 하고 무겁고 구조적 개발 기술을 도입하는 결과를 가져

다준다는 것을 인식하게 되었는데, 이들 대부분이 오늘날까지 여전히 쓰이고 있다. 이러한

경험 때문에 대다수의 데이터 전문가는 1990년대의 『오브젝트 테크놀로지 레볼루션9』에 의

해 소개된 진화적 기술이 단지 1970년대의 ‘일단 짜보고 고치기’와 다를바 없는 재탕이라고

믿게 되었다. 솔직히 말해서, 많은 객체 실천가들이 사실상 그런 방법으로 작업을 했다. 그

들은 진화적 접근론과 질이 낮은 것을 동등하게 생각했다. 하지만 애자일 진영이 나타남으

로써 그와 같은 경우는 되풀이 되지 않을 것이다. 결국 대다수의 데이터 지향적 방법론은

과거의 프로세스를 통한 순차적이고, 전통적인 방법에 의해 궁지에 몰리는 양상을 띄게 되

었고, 이는 대게 애자일 접근법의 잘못된 사용이 가져다 준 결과이다. 데이터 분야는 따라

잡아야 할 것들이 많고, 이들 대부분은 많은 시간이 소요된다.

두 번째 장애물은 부족한 도구이다. 오픈 소스의 노력(적어도 자바진영 내에서는)이 빠

르게 그 틈새를 메워주고는 있지만 여전히 부족하다. 설령 많은 노력이 ORM(object/relational

mapping) 툴과 몇몇 데이터베이스 툴 개발에 들어가고 있다 하더라도 여전히 해야 할 일들

은 많이 남아 있다. 툴 벤더가 그들의 툴 안에 리팩토링 기능을 구현하기 위해 수년동안 프

로그래밍한 것처럼-사실, 지금의 통합 개발 환경(IDE)을 찾아보더라도 이 같은 기능은 제

공하지 않는다–데이터베이스 툴 벤더도 동일한 기능을 구현하려면 수년이 걸릴 것이다.

분명하게 말해서, 데이터베이스 스키마의 진화적인 개발이 가능하려면 사용 가능한, 유연

한 툴이 필요하다–오픈소스 진영은 이런 틈새를 채우기 위해 분명히 시작하고 있고 아마

상업 툴 벤더도 결국 동일하게 시작할 것이라고 생각한다.

9.  Object Technology Revolution: 마이클 K.거트만, 존 R.매튜가 공통 집필한 저서로 비즈니스 데이터 처리에 있어 분산 객체 기술의 필

요성을 다룬 책.

Page 47: 리팩토링 데이터베이스 : 진화적 데이터베이스 디자인

15

1_ 진화적 데이터베이스 개발

1.7 무엇을 배웠나

개발에 있어 반복적이고 점진적인 진화적 접근법은 현대 소프트웨어 개발을 위한 디팩토

표준10

이라 할 수 있다. 프로젝트 팀이 이러한 접근방법을 사용하기로 결정했다면 데이터

전문가를 포함한 팀의 모두가 진화적인 방법으로 작업을 수행해야 한다. 다행히도 진화적

인 기술은 데이터 전문가가 진화적인 방법으로 작업이 가능하도록 해 준다. 이러한 기술에

는 데이터베이스 리팩토링, 진화적 데이터 모델링, 데이터베이스 회귀 테스트, 데이터 지

향적 아티팩트의 형상관리와 개발자 샌드박스 분리 등이 포함된다.

10. 디팩토 표준(Defecto standard): 프랑스어로 사실상의 표준이란 의미로 개발분야에서 자주 사용되는 용어

Page 48: 리팩토링 데이터베이스 : 진화적 데이터베이스 디자인

16

2 장 데이터베이스 리팩토링

"디자인은 한번 굳어버리는 순간 바로 구식이 된다."

–프레드 브룩스

2장에서는 데이터베이스 리팩토링에 감추어진 기본적인 개념을 소개하고, 그것이 무엇인지,

개발에 어떻게 적용할 수 있는지 그리고 왜 성공적인 리팩토링이 종종 어렵게 여겨지는지

에 대해 설명한다. 이 다음 장에서는 데이터베이스 스키마의 실질적인 리팩토링 프로세스

를 자세히 설명할 것이다.

2.1 코드 리팩토링

마틴 파울러(1999)는 그의 저서인 『리팩토링』에서 한 번에 하나씩 작은 단계로 코드를 재

구조화하는 훈련된 방법을 리팩토링이라 부르고, 이 프로그래밍 기법을 설명한다. 리팩

토링은 프로그래밍에 진화적인(반복적이고 점진적인) 접근론을 도입한 것으로, 코드를 서

서히 발전시켜 나가도록 해 준다. 리팩토링의 핵심 관점은 코드의 행위적 의미를 유지하

는 것이다. 리팩토링을 할 경우 기능을 추가하거나 빼서는 안 된다. 리팩토링은 단지 코드

의 디자인을 개선시키는 것이며, 그 이상도 그 이하도 아니다. 예를 들어 그림 2.1에서는

Offering 클래스의 calculateTotal() 동작을 하위클래스인 Invoice 클래스로 옮기도록 푸

쉬 다운 메서드(Push Down Method)1 리팩토링을 적용한 것이다. 이 같은 변경은 겉으로는 쉬

1. Push Down Method: 상위클래스에 있는 동작이 하위클래스 중 일부에만 관련이 있다면 그 동작을 관련된 하위클래스로 옮긴다.

Page 49: 리팩토링 데이터베이스 : 진화적 데이터베이스 디자인

17

2_ 데이터베이스 리팩토링

워보인다. 하지만 Offering 객체가 아닌 Invoice 객체와 작동하도록 이 동작을 호출하는

코드를 변경해야 할 것이다. 이런 변경을 끝내고 난 후, 이전과 마찬가지로 여전히 코드가

작동한다면 그 때야 비로소 진정한 리팩토링을 했다고 말할 수 있다. 분명한 건 코드 리팩

토링을 하기 위해서는 좋은 도구와 그것을 가능하게 하는 기술을 포함한 체계적인 방법이

필요하다는 것이다. 요즘 대부분의 현대의 통합 개발 환경(IDE)은 몇 가지 리팩토링을 제

공하며, 제공하는 리팩토링으로부터 시작하는 것은 좋은 출발이다. 그렇지만 실제로 코드

리팩토링 작업을 하려면 리팩토링한 코드가 여전이 잘 작동하고 있음을 검증해줄 최신의

회귀 테스트 코드 개발 또한 필요하다-리팩토링이 코드를 깨뜨리지 않았다는 확신이 들지

않는다면 코드 리팩토링을 신뢰할 수 없다.

그림 2.1 서브 클래스로 메서드 옮기기

많은 애자일 개발자들, 특히 익스트림 프로그래머(XPer)들은 리팩토링을 가장 중요한

개발 수행 방법으로 여긴다. 코드의 일부을 리팩토링하는 것은 if나 loop 구문을 사용하는

것만큼이나 일반적인 것이다. 훌륭한 퀄리티의 소스코드를 가지고 작업을 해야 가장 생산

적이 되기 때문에 코드에 인정을 두지 말고 리팩토링한다. 코드에 새로운 기능을 추가할

때 여러분이 물어봐야 할 첫 번째 질문은 “이 기능을 추가하는 데 있어 이 코드가 가능한

가장 좋은 디자인을 반영하는가?”란 질문이고, 만약 그에 대한 답변이 “예”라면 새로운 기

능을 추가하고, 만약 답이 “아니오”라면 먼저 가능한 가장 좋은 디자인이 되도록 코드를 리

팩토링하고 나서 기능을 추가하라. 겉으로 보기에는 많은 작업처럼 보인다. 하지만 실제로

는 높은 퀄리티의 소스 코드를 가지고 시작하고 그 수준을 유지하면서 리팩토링한다면 이

접근방법이 놀라울 만큼 잘 수행된다는 것을 알게 될 것이다.

Before: After:

calculateTotal()

InvoiceInvoice

Offering

calculateTotal()

Offering

Page 50: 리팩토링 데이터베이스 : 진화적 데이터베이스 디자인

18

Database Refactoring _2

2.2 데이터베이스 리팩토링

데이터베이스 리팩토링(엠블러 2003)이란 데이터베이스 스키마의 행위와 정보적 의미를 유지

한 채 그 스키마를 간단히 변경하여 디자인을 개선시키는 것을 말한다-다시 말하면, 새로

운 기능을 추가하거나 기존의 기능을 손상시켜서는 안 되며 또한 데이터를 추가하거나 이

미 존재하는 데이터의 의미를 변경해서도 안 된다. 보는 관점에 따라 데이터베이스 스키마

는 테이블과 뷰 정의 같은 구조적 관점과 저장 프로시저와 트리거 같은 함수적 관점을 모

두 포함한다. 앞으로 이런 관점에 따라 마틴 파울러가 설명한 전통적인 리팩토링을 언급할

때는 ‘코드 리팩토링(code refactoring)’이란 용어를 사용할 것이고, 데이터베이스 스키마 리팩

토링을 언급할 때는 ‘데이터베이스 리팩토링(database refactoring)’이란 용어를 사용할 것이다.

3장에서 자세하게 설명할 ‘데이터베이스 리팩토링 프로세스’는 데이터베이스 스키마에 이

러한 간단한 변경을 만들어주는 작업이다.

데이터베이스 리팩토링은 개념적으로 코드 리팩토링보다 더욱 어렵다: 코드 리팩토링은

단지 행위적 의미만을 유지하면 되지만, 반면 데이터베이스 리팩토링은 정보적 의미 또한

유지해야만 한다. 더 안 좋은 건, 데이터베이스 리팩토링은 그림 2.2에 소개된 데이터베이

스 아키텍처 결과에 따른 결합도 정도에 의해 더욱 복잡하게 된다. 결합도란 두 모듈 사이

의 의존성을 측정한 것이다; 더 높게 결합된 두 가지는 어느 한쪽의 변경이 다른 한쪽의 변

경을 반드시 필요로 할 가능성이 더 크다. 단일 애플리케이션 데이터베이스 아키텍처는 매

우 단순한 경우로-애플리케이션은 데이터베이스와 단 한 번 상호작용할 뿐이고 코드와 데

이터베이스를 병행해서 리팩토링할 수도 있고, 동시에 두 작업 모두 배포할 수 있도록 해

준다. 이런 경우는 종종 스탠드얼론 애플리케이션이나 스토브파이프 시스템2 에서 언급되

어진다. 두 번째 아키텍처는 데이터베이스와 많은 외부 프로그램이 상호작용하기 때문에

더욱 복잡하고 그 중 일부는 우리가 다루고자 하는 영역을 벗어난 것이다. 이런 경우에는

모든 외부 프로그램이 한번에 배포된다고 가정할 수 없으며, 그렇기 때문에 반드시 과거

2.  스토브파이프 시스템: 보통 레거시 시스템으로 연관된 요소의 집합이 서로 단단히 묶여있어 각각을 분화시키거나, 각 부분만을 업그레

이드 혹은 리팩토링하기 힘든 시스템이다. 스토브파이프 시스템은 새로운 시스템으로 완전히 바꾸기 전까지는 유지관리가 불가능하다.

예를 들어 새로운 하드웨어를 더 이상 추가할 수 없는 시스템이나, 프로그램의 원래 소스코드를 잃어버려 더 이상 수정이 불가능한 경

우이다.

Page 51: 리팩토링 데이터베이스 : 진화적 데이터베이스 디자인

19

2_ 데이터베이스 리팩토링

그림 2.2 데이터베이스 아키텍처의 두 종류

애플리케이션

애플리케이션

데이터베이스

데이터베이스

다른 알고 있는

애플리케이션

다른 모르는

애플리케이션

영속성

프레임워크

단일 애플리케이션 데이터베이스

다중 애플리케이션 데이터베이스

다른

데이터베이스

데이터 파일

테스트 코드

Page 52: 리팩토링 데이터베이스 : 진화적 데이터베이스 디자인

20

Database Refactoring _2

스키마와 새로운 스키마가 동시에 모두 지원되는 과도기(transition period)3 과정을 두어야 한

다. 더 자세한 것은 나중에 설명하겠다.

설령 우리가 이 책 전체에 걸처 단일 애플리케이션 환경을 논할 수도 있지만, 여러분의

실제 데이터베이스가 존재하는 환경이자, 조금밖에 다룰 수 없거나 전혀 다룰 수 없는 많

은 다른 외부 프로그램에 의해 액세스되는 다중 애플리케이션 환경에 대해 좀 더 초점을

맞출 것이다. 걱정할 필요는 없다. 3장에서는 이런 형태의 상황에서 수행하는 전략을 설

명한다.

데이터베이스 리팩토링을 환경에 적용하기 위해서 빠른 예제를 통해 단계를 밟아보

자. 몇 주 동안 뱅킹 애플리케이션을 가지고 작업해왔고 그림 2.3에 그려진 Customer와

Account 테이블에서 무언가 이상한 것이 있다는 것을 알고 있을 것이다. 정말로 Balance

컬럼이 Customer 테이블의 일부인 것이 맞는가? 그렇지 않다. 그럼 데이터베이스 디자인

을 개선하기 위해 ‘컬럼 옮기기(112쪽)’ 리팩토링을 적용해보자.

2.2.1 단일 애플리케이션 데이터베이스 환경

단일 애플리케이션 데이터베이스 환경 내에서 컬럼을 어느 한 테이블에서 다른 테이블로

이동하는 예제로부터 시작해 보자. 이것은 데이터베이스 스키마와 그것에 액세스하는 애플

리케이션 소스 코드를 완전히 컨트롤할 수 있기 때문에 여러분이 이전에 경험했던 것 중 가

장 단순한 상황일 것이다. 여기에 함축된 의미는 데이터베이스 스키마와 애플리케이션 코

드 모두를 동시에 리팩토링할 수 있다는 뜻이다–오로지 단 하나의 애플리케이션만이 데이

터베이스에 액세스하기 때문에 데이터베이스의 원래 스키마와 새로운 스키마를 동시에 모

두 지원할 필요는 없다.

이 시나리오에서 우리는 두 사람의 파트너가 짝을 지어 함께 작업하는 것을 제시하고 있

으며4 ,한 사람은 애플리케이션 프로그래밍 기술을 가지고 있어야 하고, 다른 한 사람은 데

이터베이스 개발 기술을 가져야 한다. 두 기술을 모두 가지고 있다면 아주 이상적일 것이다.

3.  과도기(transition period): deprecation period라고도 불리며 원래의 스키마에서 새로운 스키마로 교체되기까지의 인계기간을 말한다.

이 기간 동안은 두 스키마가 모두 지원되어 과거 스키마를 사용하는 모든 애플리케이션이 충분한 시간적 여유을 가지고 새로운 스키마

를 사용하도록 변경되어야 한다.

4.  익스트림 프로그래밍(XP)의 가장 큰 원칙 중 하나인 페어(pair) 프로그래밍을 말한다. 페어 프로그래밍은 코드의 질과 업무(코드)에 대

한 상호간의 의사소통을 높여주는 훈련된 방법이다. 더 자세한 내용은 켄트 벡의 ‘Extreme Programming Explained’를 참조한다.

Page 53: 리팩토링 데이터베이스 : 진화적 데이터베이스 디자인

21

2_ 데이터베이스 리팩토링

그림 2.3 고객과 계좌에 대한 초기 데이터베이스 스키마

Cus

tom

er

Cus

tom

erID

<<P

K>>

Firs

tNam

eB

alan

ce

Acc

ount

Acc

ount

ID <

<PK

>>C

usto

mer

ID <

<FK

>>

Che

ckN

oAcc

ount

s

{

even

t = b

efor

e de

lete

}

Che

ckC

usto

mer

Exi

sts

{ eve

nt =

bef

ore

upda

te |

befo

re in

sert

}

acce

sses

11

Page 54: 리팩토링 데이터베이스 : 진화적 데이터베이스 디자인

22

Database Refactoring _2

이렇게 짝을 지어 데이터베이스 스키마가 리팩토링이 필요한지 아닌지를 결정함으로써 시

작한다. 아마도 프로그래머는 스키마를 발전시킬 필요가 있다는 것과 리팩토링을 하는 가

장 좋은 방법에 대해 잘못 생각할 수도 있다. 리팩토링은 개발 샌드박스 내에서 먼저 개발

되고 테스트된다. 그것이 끝나면, 변경사항은 프로젝트 통합 환경으로 승급되고 시스템은

필요에 따라서 리빌드되고 테스트되고 고쳐진다.

개발 샌드박스에서 ‘컬럼 옮기기(112쪽)’ 리팩토링을 적용하려면 먼저 그동안의 모

든 테스트를 수행하여 통과되는지 확인한다. 테스트 주도 개발(Test-Driven Development) 접

근 방법을 수행하고 있기 때문에, 그 다음으로 새로운 테스트를 작성한다. 테스트할 것은

Account.Balance 컬럼에서 값을 액세스하는 것과 같은 것이다. 실행하면 테스트가 실패

하는 것을 보게 되는데, 그런 후에 그림 2.4에 보이는 것처럼 Account.Balance 컬럼을

도입한다. 다시 테스트를 실행하면 이번에는 테스트를 통과함을 보게 된다. 그러고 나서

기존 테스트를 리팩토링한다. 여기서 고객이 Customer.Balance 컬럼이 아닌 Account.

Balance 컬럼으로 작업을 올바르게 처리하는지 확실히 검증한다. 이들은 이런 테스트들

이 실패하는 것을 보게되고, 그러므로 Account.Balance 컬럼으로 동작하도록 처리기능을

변경한다. 이와 비슷하게 현재 Customer.Balance 컬럼과 작업하는 인출 로직 같은 테스

트 코드내에 있는 다른 코드들도 변경한다. 애플리케이션이 다시 실행된 후에는 안전상의

목적으로 Customer.Balance 컬럼에 있는 데이터를 백업하고 Customer.Balance 컬럼에

서 Account.Balance 컬럼으로 데이터를 적절히 복사한다. 이들은 데이터 마이그레이션이

안전하게 일어났다는 것을 검증하기 위해 다시 테스트를 실행한다. 스키마 변경을 완료하

기 위한 마지막 단계는 Customer.Balance 컬럼을 삭제하는 것이고, 삭제한 후에는 다시

모든 테스트를 실행하고 필요에 따라서 뭐든 고친다. 이들이 작업을 모두 끝냈다면 이들은

변경사항을 이전에 언급한 프로젝트 통합 환경으로 승급시킨다.

2.2.2 다중 애플리케이션 데이터베이스 환경

이 상황은 좀 더 복잡하다 왜냐하면 각각의 애플리케이션들이 시기적으로 다음 해나 반년

이상의 서로 다른 시간에 배포된 새로운 릴리즈를 가지고 있기 때문이다. 이러한 환경에서

의 데이터베이스 리팩토링은 Customer.Balance 컬럼을 바로 삭제하지 않는 것만 빼면 단

일 애플리케이션 데이터베이스 리팩토링과 비슷한 방법으로 수행한다. 대신 개발팀이 그

Page 55: 리팩토링 데이터베이스 : 진화적 데이터베이스 디자인

23

2_ 데이터베이스 리팩토링

그림 2.4 고객과 계좌에 대한 최종 데이터베

이스 스키마

Cus

tom

er

Cus

tom

erID

<<P

K>>

Firs

tNam

e

Acc

ount

Acc

ount

ID <

<PK

>>C

usto

mer

ID <

<FK

>>B

alan

ceC

heck

NoA

ccou

nts

{ ev

ent =

bef

ore

dele

te }

Che

ckC

usto

mer

Exi

sts

{ eve

nt =

bef

ore

upda

te |

befo

re in

sert

}

11

acce

sses

그림 2.5 과도기의 데이터베이스 스키마

Cus

tom

er

Cus

tom

erID

<<P

K>>

Firs

tNam

eB

alan

ce {

rem

oval

dat

e =

June

14

2006

}

Acc

ount

Acc

ount

ID <

<PK

>>C

usto

mer

ID <

<FK

>>B

alan

ce

Syn

chro

nize

Acc

ount

Bal

ance

{ e

vent

= o

n up

date

| on

del

ete

| on

inse

rt,

dr

op d

ate

= Ju

ne 1

4 20

06 }

Che

ckN

oAcc

ount

s

{

even

t = b

efor

e de

lete

}

Syn

chro

nize

Cus

tom

erB

alan

ce

{

eve

nt =

on

upda

te |

on in

sert

,

drop

dat

e =

June

14

2006

}C

heck

Cus

tom

erE

xist

s

{ e

vent

= b

efor

e up

date

| be

fore

inse

rt }

11

acce

sses

Page 56: 리팩토링 데이터베이스 : 진화적 데이터베이스 디자인

24

Database Refactoring _2

들의 모든 애플리케이션에 변경 사항을 업데이트하고 재배포하는 시간을 충분히 가지도록,

적어도 1.5년 동안의 ‘과도기(transition period)’를 두어 두 컬럼 모두를 동시에 지원할 필요가

있다. 그림 2.5는 과도기의 이런 데이터베이스 스키마의 일부를 보여주고 있다. 두 개의 트

리거 SynchronizeCustomerBalance와 SynchronizeAccountBalance는 두 컬럼을 동기

화된 상태로 유지하기 위해 과도기 동안 실서버 환경에서 실행된다는 것을 주목하자.

왜 그처럼 긴 기간동안 과도기를 두어야 하는가? 왜냐하면 몇몇 애플리케이션들은 현재

동작되고 있지 않은 반면 다른 애플리케이션들은 전통적인 개발 생명주기를 따라서 단지

매년 한 번 정도 릴리즈하여 동작시키기 때문이다-과도기는 반드시 프로젝트를 빨리 수행

하는 팀뿐만 아니라 늦게 처리하는 팀 또한 고려해야 한다. 게다가 두 컬럼을 모두 업데이

트하는 과정을 개별 애플리케이션들에게만 의지할 수 없기 때문에 두 값을 동기화시킬 수

있는 트리거 같은 메커니즘을 제공할 필요가 있다. 이렇게 할 수 있는 또 다른 선택은 뷰

(View)나 사후 동기화 같은 것이 있다. 5장 ‘데이터베이스 리팩토링 전략’에서 논의할 터이

지만, 그중 트리거가 가장 잘 동작한다.

과도기 과정 다음에는, 그림 2.4의 최종 데이터베이스 스키마에 있는 결과대로 트리거를

포함한 원본 컬럼을 제거한다. 안전하다고 확신할 수 있는 충분한 테스트를 거친 후에만

이런 것들을 삭제한다. 이 시점에서 리팩토링은 완료된다. 3장에서는 좀 더 자세하게 이 예

제의 구현을 가지고 작업해보자.

2.2.3 의미 유지

데이터베이스 스키마를 리팩토링할 때는 반드시 정보적 의미와 행위적 의미를 모두 유지해

야 한다-어떤 것도 추가하거나 빼지 말아야 한다. 정보적 의미는 그 정보의 사용자 관점에

서 보는 데이터베이스 내의 정보의 의미를 말한다.

정보적 의미를 보존한다는 것은, 만약 컬럼에 저장된 데이터의 값을 변경하는 경우 그

정보를 사용하는 클라이언트가 변경에 따른 영향을 받으면 안 된다는 것을 의미한다. 예를

들어 문자열 기반의 전화번호 컬럼에 ‘일반 형식 도입(193쪽)’ 리팩토링을 적용한다면 (416)

555-1234와 905.555.1212 같은 데이터를 4165551234와 9055551212로 각각 변환하는

것이다.

Page 57: 리팩토링 데이터베이스 : 진화적 데이터베이스 디자인

25

2_ 데이터베이스 리팩토링

데이터로 작업하는 데 있어 보다 단순한 코드를 사용하도록 그 포맷이 개선되었다 할지

라도, 실제적인 관점에서 보면 진짜 정보의 내용은 그대로다. 여전히 (XXX) XXX-XXX

같은 포맷 형태로 전화번호를 표시할 수 있다는 것에 유념하자; 그 같은 방법으로 저장만

할 수 없을 뿐이다.

데이터베이스 리팩토링을 다룰 때 실제적인 것에 초점을 맞추는 것은 매우 중요한 문제

이다 . 마틴 파울러는 코드 리팩토링을 하게 될 때 ‘관찰이 가능한 행동’의 문제에 대해 이

야기하는 것을 좋아한다. 그의 요점은 수많은 리팩토링을 실행하면서 여러 작은 부분에서

의미가 변경되지 않았다는 것을 확신할 수 없다는 것이다, 우리가 바랄 수 있는 것은 최선

을 다해 생각하고, 믿을 수 있는 충분한 테스트 코드를 작성하여 그리고 나서 그 의미가 변

경되지 않았다는 것을 확인해 주는 이러한 테스트를 실행하는 것이다.

우리들의 경험에 비추어 봤을 때 이와 유사한 문제는 (416) 555-1234를 4165551234로

변경하면서 데이터베이스 스키마를 변경하는 리팩토링을 실행할 때 그것의 정보적 의미를

유지하는 문제에서 다시 나타난다. 사실상 애플리케이션에서 우리가 잘 알지 못하는 약간

의 미묘한 차이로 이 정보의 의미가 바뀔 수도 있다.

예를 들어 어쩌면 (XXX)XXX-XXXX 포맷의 전화번호을 가지고 있는 데이터 열을 가

지고 작업한 리포트가 존재할지도 모르기 때문이며, 이런 리포트는 여전히 이런 데이터에

기반하고 있을 것이다. 실제적인 느낌상 여전히 같은 정보가 출력되고 있다 하더라도 현재

리포트는 XXXXXXXXXX 포맷으로 숫자를 출력하고 있어 그것을 더 읽기 힘들게 만들고

있다. 결국 문제가 발견될 때, 그 리포트는 아마도 새로운 포맷을 반영하기 위해 업데이트

가 필요하다.

마찬가지로, 행위적 의미에 대해 말할 때 그 목표는 기능 자체는 블랙박스처럼 리팩토링

을 하기 전이나 그 후도 동일하게 유지하는 것이다. 다시 말하면, 테이터베이스 스키마가

변경된 경우 이를 참조하는 애플리케이션도 이전과 동일한 기능을 여전히 수행할 수 있도

록 소스 코드를 적절히 변경해야 하는 것을 말한다. 만약 ‘계산된 메서드 도입(261쪽)’ 리

팩토링을 적용한다면 그 연산을 위해 동일한 로직을 별도로 구현하기보다는 그 메서드를

호출하는 기존의 저장 프로시저를 재가공하기를 원할지도 모른다. 전체적으로 볼 때 데이

터베이스는 여전히 같은 로직을 구현하고 있지만 이제는 단 한 곳에 계산 로직이 있을 뿐

이다.

Page 58: 리팩토링 데이터베이스 : 진화적 데이터베이스 디자인

26

Database Refactoring _2

데이터베이스 리팩토링은 데이터베이스 변환(database transformation)5 의 일부분이라는 것

을 인식하는 것이 중요하다. 데이터베이스의 변환은 의미를 바꿀 수도, 그렇지 않을 수도

있지만 데이터베이스 리팩토링은 그렇지 않다.

11장에서는 ‘비-리팩토링 변환’과 같은 여러 가지 일반적인 데이터베이스 변환에 대해

설명할 것이다. 그것은 중요하게 이해해야 하는 것일 뿐만 아니라 데이터베이스 리팩토링

내에서 자주 사용되는 단계이다. 예를 들어 고객(customer)에서 계좌(Account)로 잔액

(Balance) 컬럼을 이동하기 위해 초기의 ‘컬럼 옮기기’ 리팩토링을 적용할 때, 그 단계 중

의 하나로 ‘컬럼 제약조건 도입(190쪽)’ 리팩토링을 적용하는 것이 필요하다. 겉으로는 ‘컬

럼 제약조건 도입(180쪽)’이 완벽한 리팩토링처럼 들린다. 테이블에 빈 컬럼을 추가하는 것

은 새로운 기능이 그것을 사용하기 전까지 그 테이블의 의미를 바꾸지 않는다. 반면에 변

환(리팩토링이 아닌)은 그것이 애플리케이션의 행위를 부주의하게 변경할 수 있기 때문에

깊이 생각해야 한다. 예를 들어 만약 테이블 가운데에 컬럼을 도입(추가)하면, 전후 관계에

의존한 접근(이를테면 컬럼의 이름보다는 17번째 컬럼을 참조하는 코드)을 사용하는 프로

그램의 논리는 깨질 것이다. 더군다나 DB2 테이블에 묶인 COBOL 코드는 설령 컬럼이 테

이블의 끝에 추가된다 할지라도 코드가 새로운 스키마에 다시 묶이지 않는다면 깨질 것이다.

결국 실제적인 것은 여러분의 가이드일 것이다.

만약 ‘컬럼 도입’을 리팩토링이라고 이름 붙이거나, 혹은 그런 모든 문제에 대해 “야바-

다바-두(Yabba Dabba Do)6 ”라고 이름을 붙인다면 그것을 사용한 방식에 영향을 주었을

까? 그렇지 않기를 바란다.

5.  데이터베이스 변환(Database transformation): 단순한 변경(modify)이 아니라 그 형태를 탈바꿈한다는 뜻에서 변경이란 단어보다는

변환(transformation)이라는 단어를 사용하였다.

6.  야바-디바-두(Yabba Dabba Do): 구석기 시대를 배경으로 한 프린스톤이란 만화영화에서 극중 주인공이 신날 때 외치는 소리로, 한

때 어린 아이들의 유행어였다. 여기서는 즉흥적으로 임의의 이름을 붙이는 것을 말한다.

Page 59: 리팩토링 데이터베이스 : 진화적 데이터베이스 디자인

27

2_ 데이터베이스 리팩토링

왜 바로 앞에서 모든 것을 하지 않는가?

기존의 데이터 전문가들에 의해 자주 언급된 진정한 솔루션은 모든 것을 사전에 완벽

하게 모델링하는 것이고, 그렇게 되면 데이터베이스 스키마를 리팩토링할 필요도 없는

것이다. 설령 그것이 흥미 있는 비전이고, 몇몇 상황에서 그렇게 작업하는 것을 봐왔

다 하더라도 과거 30년간의 경험은 전체 IT 분야를 걸쳐 이런 접근방법론이 실제로 잘

수행되지 않는다는 것을 말해주고 있다. 데이터 모델링을 하는 전통적 접근방법론은

RUP과 XP 같은 현대적 방법의 진화적 접근방법론을 반영하지 못할 뿐만 아니라 비즈

니스 고객이 요구하는 새로운 기능과 기존 기능에 대한 신속한 변경사항을 사실상 반

영하지도 못한다. 간단히 말해 오래된 방식은 이제 더 이상 충분하지 않다. 1장 ‘진화

적 데이터베이스 개발’에서 논의한 것처럼 우리는 애자일 모델 주도 개발(AMDD) 방

법론을 사용하기를 권장한다. 이 방법론으로 시스템의 전체적인 ‘전망’을 확인하기 위

해 조금은 상위 수준의 모델링을 한다. 그러고 나서 Just-In-Time(JIT) 기반으로 상

세하게 모델을 전개해간다. 과다 모델링 및 과다 문서화, 그리고 불필요한 관료주의적

결과라 할 수 있는 너무 많은 산출물을 만들어 이를 유지하고 동기화시키는데 필요 이

상의 비용을 낭비하지 말고 진화적인 모델링이 갖다 주는 수익을 누릴 수 있어야 한다.

문제 도메인이 진화함에 따라, 애플리케이션 코드와 데이터베이스 스키마는 밑바닥부

터 서서히 진화하며 양쪽의 리팩토링을 통해 품질을 유지한다.

2.3 데이터베이스 리팩토링의 분류

테이블 2.1에 설명한 대로 여섯 가지의 다른 데이터베이스 리팩토링 분류를 보여준다 . 이

러한 분류화 전략은 이 책을 편성하는 것을 돕고 앞으로의 데이터베이스 리팩토링 도구의

체계화를 돕도록 소개되었다. 분류화 전략은 완벽한 것은 아니다; 예를 들어 ‘뷰로 메서드

대체(282쪽)’ 리팩토링은 아키텍처적 분류나 메서드 분류 중 어디에 놓아도 논란의 여지가

있다.(우리는 아키텍처적 분류에 맞춰 넣었다.)

Page 60: 리팩토링 데이터베이스 : 진화적 데이터베이스 디자인

28

Database Refactoring _2

표 2.1 데이터베이스 리팩토링 분류

데이터베이스 리팩토링 분류 설명 예제

구조적 (6장) 하나 또는 여러 개의 테이블이나 뷰

의 정의를 변경한다.

한 테이블에서 다른 테이블로 컬럼을 이

동하거나 다목적 컬럼을 각기 하나의 목

적을 가진 여러 개의 컬럼으로 분리.

데이터 품질 (7장) 데이터베이스 내에 담겨진 정보의

질을 향상시키는 변경.

컬럼을 널 값을 ‘허용안함’으로 설정하

여 컬럼이 항상 어떤 값을 갖도록 보장

하거나, 일관성을 보장하기 위해 컬럼에

일반 형식(common format)을 도입.

참조무결성 (8장) 참조된 행이 다른 테이블 내에 존재

하고 있음을 보장하며 (또는) 해당

행이 적절히 삭제되어 더 이상 필요

하지 않다는 것을 보장하는 변경.

두 개의 엔터티 및 데이터베이스 외부에

서 예전에 구현된 코드 사이의 케스케이

딩 삭제를 활성화시키는 트리거를 추가.

아키텍처적 (9장) 데이터베이스와 상호작용하는 외부

프로그램을 전체적으로 개선시키는

변경

공용 코드 라이브러리에 있는 기존 자바

오퍼레이션을 데이터베이스에 있는 저

장 프로시저로 대체. 저장 프로시저화

함으로서 비 자바 애플리케이션에서도

사용이 가능하게 한다.

메서드 (10장) 메서드(저장 프로시저, 저장 함수, 또

는 트리거) 의 품질을 향상시키는 변

경. 대부분의 코드 리팩토링이 데이터

베이스 메서드에도 적용 가능하다.

쉽게 이해할 수 있도록 저장 프로시저의

이름을 변경.

비-리팩토링 변환 (11장) 데이터베이스 스키마의 의미를 변경. 기존 테이블에 새로운 컬럼을 추가.

2.4 데이터베이스 냄새

마틴 파울러는 1997년 코드 안에 있는 일반적인 문제의 분류로서 그 코드가 리팩토링

이 필요함을 알려주는 ‘코드 냄새(Code Smell)’란 개념을 소개하였다. 일반적인 코드 냄새는

switch 문, 긴 메서드(long method), 중복된 코드와 기능에 대한 욕심(feature envy)7 을 포함한다.

마찬가지로 데이터베이스 냄새란 잠재적으로 리팩토링이 필요한 것을 말한다(엠블러 2003).

이러한 냄새에는 다음과 같은 것이 있다:

▒ 다목적 컬럼. 컬럼이 여러 가지 목적으로 사용된다면 소스 데이터가 그 목적에 맞게

‘올바르게’ 사용되도록, 하나 또는 여러 개의 다른 컬럼의 값을 검사하는 여분의 코

7.  기능에 대한 욕심: 클래스 또는 인터페이스가 필요 이상으로 다른 클래스와 관련있는 메서드 즉, 당장은 필요 없는 기능인데도 미래에

이러저러한 것이 생길 것이라는 불필요한 예측을 통해, 지나치게 추상화를 많이 한다던가, 쓰지도 않는 메서드를 구현하는 경우. 이 같

은 경우는 push down method등과 같은 리팩토링 대상이다.

Page 61: 리팩토링 데이터베이스 : 진화적 데이터베이스 디자인

29

2_ 데이터베이스 리팩토링

드가 존재한다. 예로 어떤 컬럼이 고객일 경우 고객의 생일을 저장하고 직원일 경우

직원의 고용일을 저장하도록 사용된 경우다. 더 안 좋은 것은 지금 지원하고 있는

기능에 의해 제한되는 경우다-예로 직원의 생일은 어떻게 저장할 것인가?

▒ 다목적 테이블. 마찬가지로 테이블이 여러 가지 타입의 엔터티를 저장하기 위해 사용

된다면 결함이 있는 디자인이라 할 수 있다. 예로, 일반적인 Customer 테이블이 개

인과 법인에 대한 모든 정보를 저장하도록 사용된 경우다. 이 때의 문제점은 개인과

법인은 서로 다른 데이터 구조를 갖는다는 것이다-즉 개인은 이름과 성을 가지지만,

법인은 단순히 법적 이름만을 갖는다. 일반적인 Customer 테이블은 다른 것은 그렇

지 않을지 모르겠지만 몇 가지 고객 유형에 대해 널(NULL) 값인 컬럼을 가지게 된다.

▒ 여분의 데이터(Redundant Data). 여분의 데이터는 데이터가 여러 장소에 저장될 때 데이

터의 불일치가 발생할 가능성이 있기 때문에 데이터베이스 운영상 심각한 문제이다.

예를 들어 고객을 나타내는 정보는 조직 내에서 다른 여러 곳에 저장된다. 사실상

많은 기업들은 그들의 고객이 실제로 누구인지 그 정확한 리스트를 한 곳에 두기가

힘들다. 문제는 한 개의 테이블에는 존 스미스가 메인 가 123번지에 살고 있고, 다

른 테이블에는 엘름 가 456번지에 살고 있다고 나온 경우이다. 이 경우, 실제 이 사

람은 메인 가 123번지에 살았었지만, 작년에 이사를 한 경우로 불행히도 존이 회사

내에 있는 그의 정보를 가지고 있는 각각의 애플리케이션에 대해 두 번의 주소 변경

을 하지 않았기 때문이다.

▒ 너무 많은 컬럼을 가진 테이블. 테이블이 너무 많은 컬럼을 가지게 될 때는 테이블의 응

집도가 떨어지게 된다-아마도, 여러 개의 엔터티를 하나의 테이블로 설계한 결과일

것이며, Customer 테이블은 세 개의 다른 주소(선적, 빌링, seasonal) 또는 몇 개

의 전화번호(자택, 직장, 핸드폰 등)를 담고 있을 것이다. 이 같은 경우는 Address와

PhoneNumber 테이블을 추가하여 이러한 구조를 정규화할 필요가 있다.

▒ 너무 많은 행을 가진 테이블. 대량 테이블은 성능 문제를 나타낸다. 예를 들어 백만 개

의 행을 가진 테이블을 조회하는 것은 시간이 많이 소모되는 일이다. 이 때는 몇 개

의 컬럼을 다른 테이블로 옮기는 수직 테이블 분할을 사용하거나, 몇 개의 행을 다

른 테이블로 옮기는 수평 테이블 분할을 사용할 수 있다. 두 전략 모두 테이블의 크

기를 줄여 잠재적인 성능 향상을 가져다 준다.

▒ ‘스마트(Smart)’ 컬럼. 스마트 컬럼은 데이터 내의 다른 위치별로 다른 개념을 나타낸다.

예를 들어 고객 ID 처음 4자리는 고객의 본점 코드를 나타낸다. 이렇듯 더욱 세분

Page 62: 리팩토링 데이터베이스 : 진화적 데이터베이스 디자인

30

Database Refactoring _2

화된 정보(예로, 본점 ID)로 컬럼을 파싱해야 하기 때문에 고객 ID는 스마트 컬럼이

라 할 수 있다. 또 다른 예로는 XML 데이터 구조를 저장하는 데 사용한 텍스트 컬

럼을 들 수 있다; 분명히 XML 데이터 구조를 좀 더 작은 데이터 필드로 파싱할 수

있다. 스마트 컬럼은 종종 어떤 시점에서 데이터를 구성하는 데이터 필드로 재구성

되어, 데이터베이스가 각 요소를 쉽게 처리하게 할 필요가 있다.

▒ 변경에 대한 두려움. 무언가를 깨뜨릴지 모른다는 두려움 때문에 데이터베이스 스키

마를 변경하는 것을 두려워한다면–예를 들어 데이터베이스에 액세스하는 애플리

케이션이 50개 정도 있다면-그것은 스키마를 리팩토링할 필요가 있다는 가장 확실

한 증표이다. 변경에 대한 두려움은 심각한 기술적 위험 요소가 여러분의 손에 달려

있다는 좋은 표시이며, 단지 한동안 더 나쁘게 될 뿐이다.

단지 무언가 냄새가 난다고 해서 그것이 나쁘다고 여기지 않는 것이 중요하다. 림버거 치

즈 는 그것이 아주 잘 숙성된 것임에도 불구하고 나쁜 냄새가 난다. 하지만 우유 냄새가

나쁠 때는 문제가 있다. 무언가 냄새가 난다면 일단 그것을 살펴보고, 생각하고, 그리고 그

것이 맞다면 리팩토링을 해라.

2.5 어떻게 데이터베이스 리팩토링을 적합하게 할 것인가

RUP(Rational Unified Process), XP(Extreme Programming), AUP(Agile Unified Prodess), 스크럼, 그

리고 동적 시스템 개발 방법론(DSDM)을 포함한 현대의 소프트웨어 개발 프로세스는 사실

상 모두 진화적이다. 크래이그 라만은 정보 기술(IT) 분야를 선도하는 리더들 사이에서 압

도적으로 지지하는 진화적 접근 방법과 그 연구 결과를 요약하고 있다. 불행하게도 대부분

의 데이터 지향적 기술은 사실상 순차적이라서, 논리적 모델링이나 물리적 모델링 같은 상

대적으로 좁은 업무을 수행하는 전문가들을 의지한다. 문제는 여기에 있다–두 그룹은 함

께 공동으로 작업할 필요가 있지만 둘 모두 서로 다른 방법으로 그것들을 하기를 원한다.

우리의 요점은 데이터 전문가들도 개발자들과 마찬가지로 현대의 전화적인 기술을 도입하

여 그 이득을 취할수 있다는 것이며, 데이터베이스 리팩토링은 데이터 전문가에게 반드시

필요한 몇 가지 중요한 기술 중 하나이다. 불행히도 데이터 분야는 1990년대의 객체 혁명

에 편승하지 못했다. 그 말은 애플리케이션 프로그래머가 오늘날 누리고 있는 진화적인 기

술을 습득할 기회를 놓쳤다는 의미이기도 하다. 많은 면에서 데이터 분야는 고도의 협업과

공동성을 갖게 하는데 한 발 더 앞에 전진해 있는 진화적 개발 방법론을 취하고 있는 애자

Page 63: 리팩토링 데이터베이스 : 진화적 데이터베이스 디자인

31

2_ 데이터베이스 리팩토링

일 혁명도 또한 놓치고 있다. 데이터베이스 리팩토링은 코드 리팩토링이 애플리케이션 구

현 기술이듯이 단지 데이터베이스 구현 기술이다. 데이터베이스 스키마를 리팩토링하여 추

가가 용이하도록 할 수 있다. 종종 데이터베이스에 새로운 컬럼이나 저장 프로시저 같은

새로운 기능을 추가할 필요가 있다는 것을 알게 되지만, 기존의 디자인은 새로운 기능을

쉽게 지원할 수 있는 가장 좋은 디자인이 아니다. 새로운 기능을 쉽게 추가할 수 있도록 먼

저 데이터베이스 스키마를 리팩토링하는 것으로 시작하고, 리팩토링을 성공적으로 적용하

고 나서는 새로운 기능을 추가한다. 이러한 접근 방법의 이점은 천천히 수행하지만 일관성

있게 데이터베이스의 디자인의 질을 개선시킨다는 점이다. 이 같은 프로세스는 데이터베이

스의 이해와 사용을 용이하게 할 뿐만 아니라 또한 시간에 걸쳐 쉽게 발전시킬 수 있다: 다

시 말하면, 전체적인 개발 생산성을 향상시킨다.

그림 2.6은 객체와 관계형 데이터베이스 기술 모두를 사용하는 현대의 프로젝트에서 발

생하는 핵심 개발 활동(activity)에 대한 상위 수준의 개요를 제공한다. 모든 화살표가 양

방향임을 주목하라. 필요에 따라서는 액티비티 사이의 앞, 뒤를 반복하여 탐색하라. 또한

시작 지점도 종료 지점도 정의돼 있지 않다는 것에 주의하라–이것은 분명히 전통적이거나,

순차적인 프로세스가 아니다.

데이터베이스 리팩토링은 진화적인 데이터베이스 개발이란 그림의 단 일부일 뿐이다. 데이

터 모델링을 위해서는 여전히 진화적이고/애자일한 접근방법을 취할 필요가 있다. 여전히

데이터베이스 스키마를 테스트 할 필요가 있으며, 형상관리 시스템하에 두어야 한다. 그리

고 여전히 적절하게 튜닝할 필요도 있다. 이러한 주제는 다른 책을 위해 남겨두도록 하겠다.

그림 2.6 진화적인 개발 프로젝트에서의 잠재적인 개발 액티비티

개념적 데이터 모델링

개체 모델링

물리적 데이터 모델링

O/R 매핑

애플리케이션 구현

데이터베이스구현

튜닝

Page 64: 리팩토링 데이터베이스 : 진화적 데이터베이스 디자인

32

Database Refactoring _2

2.6 데이터베이스 스키마를 보다 쉽게 리팩토링하기

결합도(coupling)가 높다면 무언가 리팩토링하는 게 더 어렵다. 이것은 코드 리팩토링에서는

당연한 사실이며, 데이터베이스 리팩토링에서는 더욱 틀림없는 사실이다. 우리의 경험상

으로는 행위적 이슈(예를 들어 코드)나 많은 데이터베이스 서적들이 다루려고 하지 않았던

무언가를 고려하기 시작할 때 결합도는 심각한 이슈가 된다. 가장 리팩토링이 쉬운 시나리

오는 단일 애플리케이션 데이터베이스일 것이다. 왜냐하면 데이터베이스 스키마는 오로지

그 자체와 단 하나의 애플리케이션에만 결합돼 있기 때문이다.

데이터베이스

애플리케이션

다른 데이터베이스

다른 알고 있는 애플리케이션

다른 모르는 애플리케이션

영속성 프레임워크

테스트 코드데이터 파일

그림 2.7 외부 프로그램과 높게 결합된(coupled) 데이터베이스

그림 2.7에 그려진 다중 애플리케이션 데이터베이스 아키텍처와 관련된 데이터베이스 스

키마는 애플리케이션 소스 코드, 영속성 프레임워크와 ORM(Object-Relational Mapping) 도구8

및 다른 데이터베이스(복제, 데이터 추출/적재 등등)들과 데이터 파일 스키마, 테스팅 코드

등과 잠재적으로 결합돼 있다. 이러한 결합도를 효과적으로 줄이는 방법은 데이터베이스

와 관련된 액세스를 캡슐화하는 것이다. 그림 2.8에 묘사된 대로 외부 프로그램이 영속성

계층(persistence layer)을 통해 데이터베이스에 액세스하도록 함으로써 이렇게 할 수 있다. 영

8.  영속성 프레임워크 와 ORM툴: 비슷한 말로서 데이터 모델에 대한 객체의 도메인 모델을 표현한 것으로, EJB의 CMP나 BMP 또는

TopLink, Hibernate, iBATIS등을 말한다.

Page 65: 리팩토링 데이터베이스 : 진화적 데이터베이스 디자인

33

2_ 데이터베이스 리팩토링

속성 계층은 여러가지 방법으로 구현될 수 있다–데이터 액세스 객체(DAO)9

를 통해서나,

필요한 SQL 코드를 구현하거나, 프레임워크 의해서나, 저장 프로시저를 통해서, 또는 심

지어 웹 서비스를 통해서도 구현될 수 있다. 다이어그램에서 보는 것처럼, 결코 결합도를

Zero로 끌어 내릴 수는 없지만 무언가 다루기 쉽도록 확실히 줄일 수는 있다.

그림 2.8 액세스 캡슐화(encapsulating)를 통한 결합도 줄이기

2.7 무엇을 배웠나

코드 리팩토링은 코드를 조금씩 재구성하기 위한 훈련된 방법이자, 디자인의 질을 개선시키

는 진화적인 방법이다. 코드 리팩토링은 코드의 행위적 의미를 유지한다. 기능을 추가하거

나 그 기능을 제거하지도 않는다. 마찬가지로, 데이터베이스 리팩토링은 데이터의 행위적

의미와 정보적 의미 모두를 유지한 채 그 디자인을 개선시키기 위해 데이터베이스 스키마를

단순히 변경하는 것을 말한다. 데이터베이스 리팩토링은 데이터 전문가들이 데이터베이스

를 개발하는 데 있어 진화적인 접근방법론을 사용할 수 있도록 하는 핵심 기술 중 하나이다.

데이터베이스와 연관된 결합도가 보다 높다면 리팩토링하는 데 더 많은 어려움이 따른다.

9.  DAO(Data Access Object): J2EE소프트웨어 디자인 패턴중 하나로 비즈니스 로직에서 데이터접근 로직을 별도의 인터페이스로 분리

하여 만드는 패턴(Core J2EE Design Pattern 참조)

데이터베이스

애플리케이션

다른 데이터베이스

다른 알고 있는 애플리케이션

다른 모르는 애플리케이션

영속성 프레임워크

테스트 코드

데이터 파일

Page 66: 리팩토링 데이터베이스 : 진화적 데이터베이스 디자인

34

3 장 데이터베이스 리팩토링 프로세스

"새로운 과학적 진리는 상대를 설득하여 새로운 사실을 받아들이게 하여 승리하는 것

이 아니라, 상대가 결국 세상을 떠나고 새로운 사실에 익숙한 세대가 자연스럽게 자라

날 때 비로서 승리하는 것이다."

–막스 플랑크

3장에서는 데이터베이스 내에서 단일 리팩토링을 구현하는 방법을 설명한다. 구조적 리팩

토링인 ‘컬럼 옮기기(112쪽)’를 적용하는 예제를 통해 작업을 진행해 보자. 설령 이 리팩토

링이 간단해 보일지 모르지만, 프로덕션(실 서버) 환경에서 안전하게 구현하려면 상당히

복잡한 것임을 알게 될 것이다. 그림 3.1은 데이터베이스 디자인을 향상시키기 위한 간단

한 변경으로 Customer.Balance 컬럼을 Account 테이블로 옮기는 방법을 소개한다.

1장 ‘진화적 데이터베이스 개발’에서 논리적 작업 샌드박스 개념을 소개하였다-논리적

작업 샌드박스란 개발 샌드박스로서 개발자 자신만의 소스 코드와 작업할 데이터베이스에

대한 복사본을 가지고 있다. 프로젝트 통합 환경은 팀 멤버가 그들의 변경사항을 승급시켜

서 테스트하는 곳이며 시스템에 대한 사전 프로덕션 환경1, 통합 환경, 사용자 적응 테스

트 환경 그리고 프로덕션 환경이 있다. 데이터베이스 리팩토링의 까다로운 처리들은 개발

샌드박스 내에서 이루어진다-이 같은 환경 내에서 다른 환경으로 승급하기 이전에 충분히

깊이 생각하고, 그에 따라 구현하고, 테스트하여야 한다. 3장의 초점은 개발 샌드박스 내

에서 수행되는 작업에 맞춰져 있다. 4장 ‘프로덕션으로 배포하기’에서는 변경사항 승급과

리팩토링의 배포 결과로 일어날 수 있는 일을 다룬다.

1.  사전 프로덕션 환경(preproduction environment): 사전적 의미는 ‘생산 준비단계’이지만 여기서는 사전 프로덕션이란 용어로 의미를

전달한다.

Page 67: 리팩토링 데이터베이스 : 진화적 데이터베이스 디자인

35

3_ 데이터베이스 리팩토링 프로세스

그림 3.1 Customer.Balance 컬럼을 Account 테이블로 옮기기

개발 샌드박스 내에서 일어나는 일을 설명해야 하기 때문에 이 프로세스는 단일 애플리

케이션 데이터베이스와 다중 애플리케이션 데이터베이스 환경 모두에 적용한다. 두 상황

간의 실제적인 차이점이란 오직 다중 애플리케이션 시나리오에서는 과도기(나중에 좀 더

설명하겠다)가 좀 더 오랫동안 필요하다는 것뿐이다.

그림 3.2는 데이터베이스 리팩토링 프로세스의 개요를 UML 2의 액티비티 다이어그램

으로 표현한 것이다. 이 프로세스는 결함을 수정하기 위한 새로운 요구사항의 구현을 시

도하려는 개발자로부터 시작한다. 개발자는 데이터베이스 스키마를 리팩토링할 필요가 있

다는 것을 알게 된다. 이 예제에서 개발자인 ‘에디’는 자신의 애플리케이션에 새로운 타입

의 재정 처리 코드를 추가하고 나서 Balance 컬럼이 실제로는 Customer 엔터티가 아닌

Account 엔터티를 설명하고 있다는 것을 알게 되었다. 에디는 페어(pair) 프로그래밍(윌리

엄 & 케슬러 2002)과 애자일 모델 주도 개발(AMDD)2 (엠블러 2002) 같은 일반적인 애자일 수행

방법론을 따르기 때문에 그를 도와 리팩토링을 적용할 수 있도록 해줄 그 팀의 데이터베이

스 관리자(DBA)인 ‘베버리’에게 도움을 얻기로 결정한다. 그 둘은 다음과 같은 액티비티를

통해 반복적으로 작업을 수행한다:

▒ 데이터베이스 리팩토링이 필요한지 검증한다.

▒ 가장 적절한 데이터베이스 리팩토링을 선택한다.

2. 애자일 모델 주도개발(AMDD), 애자일 모델링(AM)같은 모델링을 말한다.

Page 68: 리팩토링 데이터베이스 : 진화적 데이터베이스 디자인

36

The Process of Database Refactoring _3

그림 3.2 데이터베이스 리팩토링 프로세스

리팩토링이 필요한지 검증한다

테스트 실행

스키마 변경

데이터 마이그레이션(선택적)

[실패]

[통과]

[요구되지 않음]

[작업 완료]

[계속 작업]

올바른 리팩토링을 선택한다

단위 테스트 작성

원본 스키마를 더 이상 사용하지 않는다(선택적)

외부 액세스 프로그램 수정

테스트 실행

리팩토링이 끝났음을 알린다

작업내용에 대한 버전 관리

[실패]

Page 69: 리팩토링 데이터베이스 : 진화적 데이터베이스 디자인

37

3_ 데이터베이스 리팩토링 프로세스

▒ 원본 데이터베이스 스키마는 더 이상 지원되지 않음(Deprecate)3을 표시한다.

▒ 리팩토링 전, 후는 물론 리팩토링 도중에도 테스트를 한다.

▒ 데이터베이스 스키마를 변경한다.

▒ 소스 데이터 마이그레이션 작업을 수행한다.

▒ 외부 액세스 프로그램을 변경한다.

▒ 회귀 테스트를 실행한다.

▒ 작업한 내용에 대해 버전 관리를 한다.

▒ 리팩토링이 끝났음을 알린다.

3.1 데이터베이스 리팩토링이 적절한지 검증한다

먼저 DBA인 베버리는 제시된 리팩토링을 해야 할 필요가 있는지 없는지를 결정한다. 여기

서 고려해야 할 세 가지 이슈가 있다:

1. 리팩토링을 하는 것이 과연 옳은가?

어쩌면 기존의 테이블 구조가 올바른 것일지도 모른다. 개발자들이 기존의 데이터베이

스 디자인을 단순히 오해하거나, 그에 대한 의견이 서로 맞지 않는 일은 일반적인 경우

이다. 이러한 오해는 실제로는 변경이 필요 없더라도 디자인의 변경이 필요하다고 믿게

만든다. DBA는 프로젝트 팀의 데이터베이스와 다른 조직의 데이터베이스에 대해 올바

른 지식을 가지고 있어야만 하고, 이와 같은 이슈에 대하여 연락을 취할 누군가를 알고

있어야 한다. 그럼으로써, 기존의 스키마가 가장 좋은 것인지 아닌지를 결정할 수 있는

보다 나은 입장을 취할 수 있다. 더 나아가 DBA는 수시로 시스템 전반에 대한 큰 그림

을 이해하고 있어야 하며, 이러한 이해는 단 하나의 프로젝트 관점에서 볼 경우 분명하

게 보이지 않을 수도 있는 중요한 통찰력을 제공한다. 하지만 우리의 예제에서는 스키

마가 변경될 필요성이 있어 보인다.

3.  Deprecate: 클래스나 인터페이스의 해당 메서드나 기능이 버전 업그레이드나 성능상의 문제로 인해 더 이상 상위 버전에서는 지원되

지 않는다는 의미로 deprecate로 표시해둔다.

Page 70: 리팩토링 데이터베이스 : 진화적 데이터베이스 디자인

38

The Process of Database Refactoring _3

2. 실제로 지금 변경이 필요한가?

이것은 보통 애플리케이션 개발자로서 이전의 경험에 근거한 ‘직관(gut call)4 ’이다. 에디

는 스키마를 변경하려는 타당한 이유가 있는가? 에디는 변경사항과 관련된 업무 요구사항

을 설명할 수 있는가? 그 요구사항이 정당한 것인가? 에디가 과거에 올바른 변경사항을 제

안했는가? 에디가 몇일 후에 마음이 변해, 베버리가 그동안 했던 변경사항을 철회해야 하

지는 않았나? 이러한 평가에 따라서 베버리는 에디가 좀 더 여러가지로 변경사항을 생각해

보도록 제의하든가 혹은 그와 함께 작업을 계속할지를 결정할 것이다. 하지만 실제로 프로

젝트 통합 환경에 변경사항을 적용하기(4장) 전에, 그들이 믿고 있는 변경사항을 바꿀 필요

성이 있는지 알기 위해 충분히 기다려야 한다.

3. 노력할 만한 가치가 있는가?

다음으로 베버리가 할 일은 리팩토링이 가져다 줄 전반적인 영향력을 평가하는 것이다.

이것을 하기 위해서 베버리는 어떤 외부 프로그램이 해당 데이터베이스 부분과 결합돼

있는지 반드시 이해해야 한다. 이러한 지식은 베버리가 엔터프라이즈 아키텍트와 데이

터베이스 운영 관리자 및 애플리케이션 개발자 그리고 다른 DBA들과 일하면서 많은

시간에 걸쳐 쌓아올린 것이다. 베버리가 그 영향력을 확신하지 못할 때는 그녀의 직관

으로 밀고 나갈지 혹은 베버리가 적절한 도움을 줄 사람과 이야기할 동안 개발자가 기

다리도록 할지 결정해야 한다. 그녀의 목표는 성공적인 데이터베이스 리팩토링 구현을

확신하는 것이다–만약 이 리팩토링을 적용하기 위해 50개의 다른 애플리케이션을 업

데이트하거나, 테스트 및 재배포할 필요가 있다면, 리팩토링을 속행하는 것은 어려운

일로 보인다. 설령 단 하나의 애플리케이션만이 데이터베이스에 액세스한다 할지라도

데이터베이스 리팩토링을 적용하기 원하는 스키마의 일부에 너무 지나치게 결합돼 있

다면, 간단히 말해 리팩토링을 할 만한 가치는 없는 것이다. 우리의 예제에서, 그녀는

디자인 문제가 너무 심각하여 비록 많은 애플리케이션이 그 영향을 받는다 할지라도 리

팩토링을 구현하기로 마음 먹는다.

4.  gut call: 굳이 뉘앙스가 비슷한 우리말로 끼워 맞추면 ‘본능’이라고 표현할 수도 있지만, 여기서는 좀 더 문장에 어울리도록 ‘직관’이라

고 표현하였다.

Page 71: 리팩토링 데이터베이스 : 진화적 데이터베이스 디자인

39

3_ 데이터베이스 리팩토링 프로세스

작은 단계로 수행하라

데이터베이스 리팩토링은 작은 단계로 스키마를 변경한다. 각각의 리팩토링은 한번에

하나씩만 적용한다. 예를 들어 기존의 컬럼을 옮기고, 이름을 변경하고, 일반 형식을

적용할 필요가 있다고 가정해 보자. 이 모든 것을 한꺼번에 하는 대신에 한번에 한 단

계식 수행한다. 먼저 ‘컬럼 옮기기(112쪽)’를 성공적으로 구현하고, 그러고 나서 ‘컬럼

명 바꾸기(137쪽)’를 구현하고, 그러고 나서 ‘일반 형식 도입(193쪽)’을 적용한다. 이렇

게 하는 것의 장점은 비록 실수를 하더라도 문제가 단지 변경한 스키마의 일부에만 존

재하기 때문에 버그를 쉽게 발견할 수 있다는 것이다.

3.2 가장 적절한 데이터베이스 리팩토링을 선택한다.

이 책에서 보는 것처럼, 잠재적으로 수많은 리팩토링을 데이터베이스 스키마에 적용할 수

있다. 상황에 맞는 가장 적절한 리팩토링이 무엇인지 결정하려면, 제일 먼저 직면한 문제

를 분석하고 이해해야만 한다. 에디가 처음 베버리에게 접근했을 때, 이러한 분석과정을 했

을 수도 있고, 그렇지 않았을 수도 있다. 예를 들어 곧장 베버리에게 다가가서는 Account

테이블에 현재 잔액을 저장할 필요가 있다고 말하고, 그렇기 때문에 새로운 컬럼(190쪽에

소개된 ‘컬럼 도입’ 변환을 통해서)을 추가해야 한다고 할 수도 있다. 하지만 그가 알아채지

못한 것은 그 컬럼이 잘못된 장소라 할 수 있는 Customer 테이블에 이미 존재한다는 사실

이다-에디는 그 문제점을 바르게 지적했지만, 그에 따른 해결책을 정확히 제시하지는 못

했다. 베버리는 기존 데이터베이스 스키마에 대한 지식에 근거하여 에디에 의해 지적된 문

제를 다시 이해할 것이고, 새로운 컬럼을 추가하는 대신 ‘컬럼 옮기기(112쪽)’ 리팩토링을

적용하도록 제안할 것이다.

Page 72: 리팩토링 데이터베이스 : 진화적 데이터베이스 디자인

40

The Process of Database Refactoring _3

가끔 데이터는 다른 곳에 있을 수 있다

여러분의 데이터베이스가 조직 내에 있는 유일한 데이터 소스가 아닐 수 있다. 좋은

DBA는 가장 좋은 데이터 소스를 결정하기 위해서 적어도 기업 내의 다양한 데이터

소스를 대략적으로 알고 있어야 한다. 예제에서는 다른 데이터베이스가 잠재적으로

Account 정보에 대한 공식 저장소가 될 것이다. 그 같은 경우에는 진정한 리팩토링은

‘공식 데이터 소스 사용(288쪽)’이기 때문에 ‘컬럼 옮기기’ 리팩토링은 상황에 맞지 않

는 것일 수 있다.

3.3 원본 데이터베이스 스키마는 더 이상 지원되지 않음을 표시한다.

다중 애플리케이션이 데이터베이스를 액세스한다면 리팩토링을 할 수 없거나 리팩토링을

한다 하더라도 동시에 그 모든 프로그램에 배포할 수 없다는 가정하에 작업을 할 필요가

있을 것이다. 그보다도, 변경하기 원하는 스키마의 원래 부분을 유지하는 과도기(transition

period)라 부르는 기간을 가져야 한다(Sadalage & Schuh 2002; Ambler 2003). 과도기 동안에는 스

키마의 원본과 새로운 스키마를 동시에 모두 지원하여, 다른 애플리케이션 팀이 그들의 시

스템을 리팩토링하고 재배포할 시간적인 여유를 제공해야 한다. 전형적으로 과도기 기간

은 몇 년이 아니라면 몇 분기 동안 지속된다. 완전한 리팩토링을 구현하기 위해 될 수 있는

한 오랜 시간을 갖는 것은 가능한 많은 프로세스를 자동화하기 위해 필요한 배경 음악과도

같은 것이다. 하지만 기간이 몇 해를 넘기면, 부서 내의 사람들이 바뀌며, 프로세스의 일부

가 수동적으로 바뀔 수 있는 위험도 있다. 앞서 한 말은, 단일 애플리케이션 데이터베이스

환경이라 할지라도 여전히 여러분의 팀은 프로젝트 통합 샌드박스 내에서 단 며칠간이라도

과도기 과정이 필요하다는 말이다-팀원들은 업데이트된 데이터베이스 스키마와 작업할 그

들의 코드를 리팩토링하고 재 테스트할 필요가 있다.

그림 3.3은 다중 애플리케이션 시나리오 내에서의 데이터베이스 리팩토링 생명주기(life

cycle)를 그린 것이다. 먼저 프로젝트 범위 내에서 리팩토링을 구현한다. 그리고 리팩토링

이 성공적이라면, 마지막으로 프로덕션 환경에 배포한다. 과도기 동안에는 원본 스키마와

Page 73: 리팩토링 데이터베이스 : 진화적 데이터베이스 디자인

41

3_ 데이터베이스 리팩토링 프로세스

새로운 스키마가 모두 존재하여 어떠한 업데이트도 올바르게 지원된다는 확신을 줄 수 있

는 충분한 테스트 발판 코드(scaffolding code)5가 있어야 한다.

그림 3.3 다중 애플리케이션 시나리오에서의 데이터베이스 리팩토링 생명주기(life cycle)

과도기 동안에는 다음 두 가지를 가정해야 한다: 첫째, 일부 애플리케이션은 원본 스키마

를 사용하지만 반면, 또 다른 일부는 새로운 스키마를 사용한다. 둘째, 애플리케이션은 스

키마의 두 버전 모두가 아니라 오직 단 하나의 버전만을 가지고 작동해야 한다. 예제에서

일부 애플리케이션은 Customer.Balance와 작동하고 다른 일부는 Account.Balance와 작

동한다. 하지만 동시에 둘 모두와 작동하지는 않는다. 어떤 컬럼을 사용하든지 애플리케이

션은 모두 정확히 실행되어야 한다. 과도기가 만료되면, 원본 스키마와 테스트 발판 코드

(scaffolding code)는 제거되고 데이터베이스는 다시 테스트된다. 이 시점에서 모든 애플리케이

션은 Account.Balance 컬럼과 작동한다고 가정한다.

그림 3.4는 원본 데이터베이스 스키마를 그린 것이고, 그림 3.5는 Customer.Balance 컬

럼에 ‘컬럼 옮기기’ 리팩토링을 적용했을 때의 과도기 동안의 데이터베이스 스키마를 보여

준다. 그림 3.5에서 변경사항은 볼드체로 보여주며, 이 책 전체에 걸처 같은 스타일을 사용

한다. 어떻게 두 버전의 스키마가 이 기간 동안 지원되는지 주목한다.

Account.Balance 컬럼이 추가되었으며, Customer.Balance는 2006년 6월 14일 이후에

제거되도록 표시되었다. 새로운 애플리케이션 코드는 Account.Balance와 작동하지만,

Customer.Balance 컬럼의 값은 최신 상태로 유지하지 않는다는 가정하에 두 컬럼에 있는

값을 동기화된 상태로 유지하도록 트리거(Trigger) 또한 도입되었다. 마찬가지로, 새로운 스

키마를 사용하도록 리팩토링되지 않은 과거 애플리케이션 코드도 Account.Balance 컬럼

이 최신의 상태로 유지되는 것을 알지 못한다고 가정한다. 이 트리거는 데이터베이스 테스

5. 테스트 발판 코드(scaffolding code): 어떤 프로그램이나 알고리즘을 테스트하기 위한 코드

리팩토링 구현 과도기 리팩토링 완료

리팩토링된 스키마 및 테스트 발판 코드(scaffolding code)를 프로덕션 환경에 배포한다

원본 스키마와 테스트 발판 코드를 프로덕션 환경에서 제거한다

Page 74: 리팩토링 데이터베이스 : 진화적 데이터베이스 디자인

42

The Process of Database Refactoring _3

트 발판 코드(scaffolding code)의 한 예로써, 데이터베이스를 ’맞붙이는데(glued together)’ 필요

한 간단하고 일반적인 코드이다. 이러한 코드도 마찬가지로 Customer.Balance와 동일한

제거 날짜를 지정해 두었다. 모든 데이터베이스 리팩토링에 과도기가 필요한 것은 아니다.

이를테면 ‘컬럼 제약조건 도입(190쪽)’이나, ‘표준 코드 적용(167쪽)’ 리팩토링은 컬럼에 제

한된 값만을 취하도록 해서 간단히 그 데이터의 품질을 향상시킬 수 있기 때문에 과도기가

필요 없다. 제한된 값은 기존 애플리케이션과의 호환성을 깨트릴지도 모르니, 조심해서 리

팩토링해야 한다. 5장 ‘데이터베이스 리팩토링 전략’에서는 적절한 과도기 선택 전략에 대

해 논의할 것이다.

3.4 리팩토링 전, 후는 물론 리팩토링 도중에도 테스트를 한다

데이터베이스 스키마를 변경한 후에도 여전히 데이터베이스가 애플리케이션과 잘 작동하

고 있다는 것을 쉽게 검증할 수만 있다면 데이터베이스 스키마에 대한 변경사항을 확실히

신뢰할 수 있다. 그리고 이렇게 하는 단 하나의 방법은 1장에서 제시한 테스트 주도 개발

(TDD) 접근 방법론을 취하는 것이다. 테스트 주도 개발에 근거한 접근방법론으로 테스트

를 수행하기 위해서는, 테스트를 작성하고, 그러고 나서 테스트에 필요한 만큼의 코드를

작성한다. 보통 데이터 정의 언어(DDL)가 이에 해당한다. 이러한 방식으로 데이터베이스

리백토링이 완전히 구현될때까지 계속한다. 잠재적으로 다음과 같은 것을 수행할 테스트를

작성한다.

▒ 데이터베이스 스키마 테스트.

▒ 애플리케이션이 데이터베이스 스키마를 사용하는 방법을 테스트.

▒ 데이터 마이그레이션 검증.

▒ 외부 프로그램 코드 테스트.

3.4.1 데이터베이스 스키마 테스트하기.

데이터베이스 리팩토링은 데이터베이스 스키마에 영향을 주므로, 데이터베이스 지향적 테

스트를 작성해야 한다. 이것이 처음에는 낯설게 들릴지 모르지만, 데이터베이스 스키마의

여러 측면을 검증할 수 있다:

Page 75: 리팩토링 데이터베이스 : 진화적 데이터베이스 디자인

43

3_ 데이터베이스 리팩토링 프로세스

그림 3.4 원본 Customer/Account 스키마

Cus

tom

er

Cus

tom

erID

<<P

K>>

Firs

tNam

eB

alan

ce

Acc

ount

Acc

ount

ID <

<PK

>>C

usto

mer

ID<<

FK>>

Che

ckN

oAcc

ount

s

{

even

t = b

efor

e de

lete

}

Che

ckC

usto

mer

Exi

sts

{ eve

nt =

bef

ore

upda

te |

befo

re in

sert

}

acce

sses

11

그림 3.5 두 버전 모두의 스키마 지원

Cus

tom

er

Cus

tom

erID

<<P

K>>

Firs

tNam

eBa

lanc

e{r

emov

al d

ate

=Ju

ne14

200

6}

Acco

unt

Acco

untID

<<P

K>>

Cus

tom

erID

<<FK

>>Ba

lanc

e

Sync

hron

izeA

ccou

ntB

alan

ce

{

even

t = o

n up

date

| on

del

ete

| on

inse

rt,

dr

op d

ate

= Ju

ne 1

4 20

06 }

Che

ckN

oAcc

ount

s

{

even

t=be

fore

del

ete

}

Sync

hron

izeC

usto

mer

Bal

ance

{ ev

ent =

on

upda

te |

on in

sert

,

drop

dat

e =

June

14

2006

}C

heck

Cus

tom

erEx

ists

{ eve

nt=

befo

re u

pdat

e |b

efor

e in

sert

}

11

acce

sses

Page 76: 리팩토링 데이터베이스 : 진화적 데이터베이스 디자인

44

The Process of Database Refactoring _3

▒ 저장 프로시저와 트리거. 애플리케이션 코드를 테스트한 것처럼 저장 프로시저와 트

리거 또한 테스트해야 한다.

▒ 참조무결성(RI). RI 규칙들, 특히 부모 행(row)이 삭제되면 그것에 강하게 종속된(coupled)

‘자식(child)’ 행도 삭제되는 캐스케이딩(cascading) 삭제는 반드시 검증되어야 한다. 실

재 규칙들, 계좌(account) 행에 대응하는 고객(customer) 같은 행은 Account 테이블에

행이 삽입되기 전에 반드시 존재해야 하며 이 역시 쉽게 테스트 돼야 한다.

▒ 뷰 정의. 뷰는 종종 흥미있는 비지니즈 로직을 구현한다. 뷰에서 주의깊게 살펴야 할

것으로 다음이 포함된다: 필터링/조회 로직이 올바르게 동작하는가? 정확한 행의

수를 반환하는가? 올바른 컬럼을 반환하는가? 컬럼이나 행의 순서가 올바른가?

▒ 기본 값(default values). 컬럼은 종종 미리 정의된 기본값을 갖는다. 기본 값이 실제로 지

정돼 있는가?(누군가가 우연찮게 테이블 정의에서 이 부분을 제거했을 수도 있다.)

▒ 데이터 불변식(data invariants). 컬럼은 흔히 정의된 제약조건 형태로 구현된 불변식을 가

진다. 예를 들어 숫자 컬럼은 1부터 7까지의 값만 갖도록 제한할 수 있다. 이런 불

변식 또한 테스트되야 한다.

데이터베이스 테스트는 많은 사람들에게 생소한 것이며, 그 결과 개발 기술로써 데이터베

이스 리팩토링을 도입했을 때 여러가지 도전에 직면하게 된다:

▒ 부족한 테스팅 스킬. 이 문제는 훈련을 통해서나, 좋은 테스팅 기술을 가진 누군가와

공동작업을 통하거나(테스팅 스킬이 없는 DBA와 DBA 스킬이 없는 테스터가 함께

작업한다), 아니면 단순한 시행착오를 겪음으로써 해결될 수 있다. 중요한 것은 이

러한 스킬을 높일 필요가 있다는 사실을 인식하는 것이다.

▒ 부족한 데이터베이스 단위 테스트. 극 소수의 조직에서만 데이터베이스 테스팅을 실천

하고 있는데, 이것은 기존 스키마에 대한 충분한 테스트 슈트가 없기 때문이기도 하

다. 과거는 불운이라 하자. 테스트 슈트 작성을 시작하기에는 지금이 가장 좋은 때다.

▒ 부족한 데이터베이스 테스팅 도구. 다행히도, 오픈소스 소프트웨어로는 테스트 데이

터 관리를 위한 DBUnit(dbunit.sourceforge.net)과 저장 프로시저 테스트를 위한

SQLUnit(sqlunit.sourceforge.net)과 같은 도구가 사용이 가능하다. 게다가, 데이

터베이스 테스팅을 위한 몇몇 상업용 도구도 있다. 하지만 이 글을 쓰고 있는 지금

까지 툴 벤더가 제공하고 있는 데이터베이스 테스팅 환경은 아직까지 개선할 여지

가 상당 부분 존재한다.

Page 77: 리팩토링 데이터베이스 : 진화적 데이터베이스 디자인

45

3_ 데이터베이스 리팩토링 프로세스

그럼 데이터베이스 스키마 변경을 어떻게 테스트할 것인가? 그림 3.5에서 보는 것처럼 과

도기 동안 반드시 검증되어야 하는 두 개의 스키마 변경사항이 있다. 첫 번째 변경사항은

Account 테이블에 Balance 컬럼을 추가하는 것이다. 이 변경사항은 데이터 마이그레이션

과 외부 프로그램 테스팅에 의해 수행되며, 다음 섹션에서 논의한다. 두 번째 변경사항은

두 개의 트리거 SynchronizeAccountBalance와 SynchronizeCustomerBalance를 추가

하는 것이며, 그 이름에서 짐작할 수 있듯이 두 데이터 컬럼을 동기화된 상태로 유지한다.

우리는 Customer.Balance가 업데이트되면 Account.Balance도 동일하게 업데이트되

는지 확인하기 위해 테스트해야 하며, 그 반대도 마찬가지다.

3.4.2 데이터 마이그레이션 검증하기.

많은 데이터베이스 리팩토링이 원본 데이터를 마이그레이션해야 하고 때로는 그 원본 데이

터조차 정제하기를 요구한다. 우리의 예제에서는, 리팩토링 구현의 일부로서 데이터 값을

Customer.Balance 에서 Account.Balance 로 복사해야 한다. 이 경우, 개별 고객의 정확

한 잔액이 실제로 복사되었는지 검증해야 한다.

‘표준 코드 적용(167쪽)’과 ‘키 통합 전략(178쪽)’같은 리팩토링에서는 실제로 데이터 값

을 ’정제(cleanse)’해야 하는데 이런 로직은 반드시 검증되어야 한다. 첫 번째 리팩토링으로,

USA나 U.S.와 같은 코드 값은 데이터베이스 전체에 걸쳐 미국을 대표하는 표준 값인 “US”

로 변환해야 할 것이다. 그리고, 이전 코드는 더 이상 사용되고 있지 않으며 이전 코드가

공식적인 값으로 적절히 변환되었음을 입증하는 테스트를 작성해야 한다. 두 번째 리팩토

링으로, 고객이 일부 테이블에서는 고객ID로 식별되고 있고, 다른 테이블에서는 사회 보장

번호(SSN)로, 그리고 또 다른 테이블에서는 전화번호로 식별되고 있는지 알아내야 할지도

모른다. 고객을 식별하기 위한 한 가지 방법을 선택할 것이고 아마도 고객ID로 식별하기로

하자. 이제 이 컬럼을 사용하도록 다른 테이블들을 리팩토링해야 한다. 이 같은 경우에는,

여러 행(row)들 사이의 관계(relationship)가 여전히 적절하게 유지되고 있음을 확인하기 위해

테스트를 작성해야 한다. (예를 들어 전화번호 555-1234가 고객인 Sally Jones 레코드를

참조하고 있다면, 전화번호에서 고객 ID 987654321로 바꾸더라도 Sally Jones 레코드는

여전히 참조되어야만 한다.)

Page 78: 리팩토링 데이터베이스 : 진화적 데이터베이스 디자인

46

The Process of Database Refactoring _3

그림 3.6 데이터베이스 스키마의 최종 버전

Cus

tom

er

Cus

tom

erID

<<P

K>>

Firs

tNam

e

Acc

ount

Acc

ount

ID <

<PK

>>C

usto

mer

ID<<

FK>>

Bal

ance

Che

ckN

oAcc

ount

s

{

even

t = b

efor

e de

lete

}C

heck

Cus

tom

erE

xist

s

{ e

vent

= b

efor

e up

date

| be

fore

inse

rt }

11

acce

sses

Page 79: 리팩토링 데이터베이스 : 진화적 데이터베이스 디자인

47

3_ 데이터베이스 리팩토링 프로세스

3.4.3 외부 액세스 프로그램 테스트하기

데이터베이스는 작업하고 있는 애플리케이션을 포함한 하나 또는 여러 개의 프로그램에 의

해 액세스된다. 이러한 프로그램은 조직 내의 다른 어떤 IT자산과 마찬가지로 반드시 검증

되어야 한다. 데이터베이스 리팩토링을 성공적으로 달성하기 위해서는 그림 3.6에 선보인

최종 스키마를 생각해 봐야 할 것이며, 외부 액세스 프로그램에서 무언가 깨지는 것이 없

는지 살펴봐야 한다. 데이터베이스 스키마를 리팩토링하는 것을 신뢰할 수 있는 단 한 가

지 방법은 이러한 프로그램들에 대해 완전한 회귀 테스트(regression test) 슈트를 가지고 있느

냐인데-맞다, 이러한 테스트 슈트를 가지고 있지 않다는 것을 잘 알고 있다. 다시 한 번 말

하지만, 테스트 슈트 구축을 시작하는데 지금보다 더 좋은 때는 없다. 모든 외부 액세스 프

로그램에 대해 각각 개별적인 데이터베이스 리팩토링을 지원하는데 필요한 모든 테스트 코

드를 작성하기를 권한다. (사실 여러분은 아닐지 몰라도, 이러한 시스템의 책임자는 이 같

은 테스트를 작성하기를 원한다.) 이러한 방법으로 작업을 한다면, 시간이 지난 후 필요한

만큼의 테스트 슈트를 구축하게 될 것이다.

3.5 데이터베이스 스키마를 변경한다

에디와 베버리는 그들의 개발 샌드박스(sandbox) 내에서 변경작업을 함께 수행한다. 그림

3.5에서 보는 것처럼, 그들은 Account.Balance 컬럼을 추가하고 또한 두 개의 트리거,

SynchronizeAccountBalance와 SynchronizeCustomerBalance를 추가해야 한다. 이것

을 수행하는 DDL 코드는 다음과 같다:

ALTER TABLE Account ADD Balance Numeric;

COMMENT ON Account.Balance ‘Move of Customer.Balance column, finaldate = 2006-06-14’;

CREATE OR REPLACE TRIGGER SynchronizeCustomerBalance

BEFORE INSERT OR UPDATE

ON Account

REFERENCING OLD AS OLD NEW AS NEW

FOR EACH ROW

DECLARE

BEGIN

Page 80: 리팩토링 데이터베이스 : 진화적 데이터베이스 디자인

48

The Process of Database Refactoring _3

IF :NEW.Balance IS NOT NULL THEN

UpdateCustomerBalance;

END IF;

END;

/

COMMENT ON SynchronizeCustomerBalance ‘Move of Customer.Balance column to Account,dropdate = 2006-06-14’;

CREATE OR REPLACE TRIGGER SynchronizeAccountBalance

BEFORE INSERT OR UPDATE OR DELETE

ON Customer

REFERENCING OLD AS OLD NEW AS NEW

FOR EACH ROW

DECLARE

BEGIN

IF DELETING THEN

DeleteCustomerIfAccountNotFound;

END IF;

IF (UPDATING OR INSERTING) THEN

IF :NEW.Balance IS NOT NULL THEN

UpdateAccountBalanceForCustomer;

END IF;

END IF;

END;

/

COMMENT ON SynchronizeAccountBalance ‘Move of Customer.Balance column to Account,dropdate = 2006-06-14’

이 글을 쓰고 있는 지금은 자동화된 데이터베이스 리팩토링 도구가 없다-그러므로 지금

당장은 모든 것을 손으로 직접 코딩해야 한다. 너무 걱정하지 말자. 이것은 때가 되면 바

뀔 것이다. 당장은 데이터베이스 스키마에 대하여 적용할 수 있는 기존 스크립트를 참조하

여 단 하나의 스크립트를 작성하면 된다. 각각의 스크립트에는 유니크(unique)한 증가 번호

를 지정해 놓기를 권한다. 그렇게 하는 가장 쉬운 방법은 숫자 1로 시작하고 새로운 데이터

베이스 리팩토링을 정의할 때마다 카운터를 증가시키는 것이다-더 쉬운 방법은 애플리케

이션의 빌드 번호를 사용하는 것이다. 그렇지만 이런 전략이 다중 팀 환경 내에서 동작하

려면 모든 팀에 걸처 유니크 넘버를 지정하든가, 아니면 개개의 리팩토링에 유니크 팀 식

별자를 추가해야 한다. 근본적으로, 팀 A의 리팩토링 번호 1701과 팀 B의 리팩토링 번호

Page 81: 리팩토링 데이터베이스 : 진화적 데이터베이스 디자인

49

3_ 데이터베이스 리팩토링 프로세스

1701은 구별돼야 할 것이다. 또 다른 옵션으로는 리팩토링에 타입스탬프(timestamp) 값을

지정하는 것인데, 이것은 5장에서 좀 더 자세하게 논의한다.

왜 개개의 리팩토링에 대해 작은 스크립트로 작업하고자 하는지 몇 가지 이유가 있다:

▒ 단순성(Simplicity). 작고 변경사항에 집중된 스크립트는 많은 단계를 포함하는 스크립

트보다 유지관리가 훨씬 쉽다. 뜻하지 않은 문제 때문에 리팩토링이 수행되지 않았

음을 알게 되면(아마도 변경된 스키마의 일부를 액세스하는 주요 애플리케이션을

변경하지 못해서일 수도 있다), 변경에 대한 두려움이 커져 앞으로 리팩토링을 쉽게

수행하지 않을 수도 있다.

▒ 정확성(Correctness). 정의된 방법으로 스키마를 서서히 발전시키기 위하여 각각의 리팩

토링을 적절한 순서로 데이터베이스 스키마에 적용하고자 할 것이다. 각 리팩토링

은 상호 간에 영향을 줄 수 있다. 예를 들어 컬럼명을 변경하고 나서 몇 주 후에 그

컬럼을 다른 테이블로 옮길지도 모른다. 두 번째 리팩토링은 코드가 새로운 컬럼명

을 참조해야 하기 때문에 첫 번째 리팩토링에 종속된다.

▒ 버전관리(Versioning). 다른 데이터베이스 인스턴스는 데이터베이스 스키마의 다른 버

전을 가질 것이다. 예를 들어 에디의 개발 샌드박스는 버전 163, 프로젝트-통합 샌

드박스의 버전은 161, QA/Test 샌드박스 버전은 155 그리고 프로덕션 데이터베이

스의 버전은 134일 수 있다. 프로젝트-통합 샌드박스의 스키마를 버전 163으로 마

이그레이션하기 위해서는 단지 데이터베이스 리팩토링 162와 163을 적용하면 된다.

버전 넘버를 간직하려면 DatabaseConfiguration 같은 일반 테이블을 도입하여 다

른 것들 가운데 현재 버전 넘버를 저장하도록 한다. 이 테이블은 5장에서 좀 더 자

세하게 다루도록 한다.

다음 DDL 코드는 과도기가 끝난 후(4장에서 다루었다)의 데이터베이스에 대해 실행된다.

마찬가지로 이 코드는 단일 스크립트 파일로 저장되어야 한다. 이 경우 식별자는 163을 따

르고 적합한 데이터베이스 스키마에 대하여 순차적인 순서로 실행한다.

ALTER TABLE Customer DROP COLUMN Balance;

DROP TRIGGER SynchronizeAccountBalance;

DROP TRIGGER SynchronizeCustomerBalance;

Page 82: 리팩토링 데이터베이스 : 진화적 데이터베이스 디자인

50

The Process of Database Refactoring _3

데이터베이스 디자인 규정을 따른다

리팩토링 구현에 있어 중요한 부분은 데이터베이스 스키마의 변경 부분은 기업의 데이

터베이스 개발 가이드라인을 따르는 것이다. 이러한 가이드라인은 데이터베이스 관리

그룹으로부터 제공되고 지원되어야 하며, 최소한 명명법 과 문서화 지침만이라도 제시

되어야 한다

3.6 소스 데이터 마이그레이션(Migration)

많은 데이터베이스 리팩토링이 어떤 면에서는 원본 데이터를 조작하기를 요구한다. 때때

로 데이터를 단지 어떤 한 위치에서 다른 위치로 이동시키기 위해 ‘데이터 옮기기(203쪽)’

를 수행할 수 있겠지만 어떤 때는, 데이터 그 자체를 정제할 필요도 있다; 이것은 ‘표준 타

입 적용(172쪽)’과 ‘일반 형식 도입(193쪽)’ 리팩토링 같은 데이터 품질 리팩토링(7장 ‘데이

터 품질 리팩토링’ 참조)에는 일반적인 것이다.

데이터베이스 스키마 변경과 마찬가지로, 필요한 데이터 마이그레이션을 수행할 스크립트

를 잠정적으로 생성해야 한다. 이런 스크립트도 다른 스크립트와 마찬가지로 관리를 쉽게

하기 위해 동일한 식별 번호를 가져야 한다. Customer.Balance 컬럼을 Account로 옮기

는 우리의 예제에서 데이터 마이그레이션 스크립트는 다음의 데이터 조작 언어(DML) 코드

를 포함해야 한다.

/*

Customer.Balance로부터 Account.Balance로의 단 한 번의 데이터 마이그레이션

*/

UPDATE Account SET Balance =

(SELECT Balance FROM Customer

WHERE CustomerID = Account.CustomerID);

기존 데이터의 품질에 따라서 원시 데이터의 정제 그 이상이 필요한지를 신속히 알아내야

할지도 모른다. 이것은 하나 또는 여러 개의 데이터 품질 데이터베이스 리팩토링 애플리케

Page 83: 리팩토링 데이터베이스 : 진화적 데이터베이스 디자인

51

3_ 데이터베이스 리팩토링 프로세스

이션을 필요로 한다. 구조적이고 아키텍처적인 데이터베이스 리팩토링을 통해 작업을 할

때는 데이터 품질 문제에 대해 눈여겨 보는 것이 좋다. 데이터 품질 문제는 시간이 지나감

에 따라 그 질이 차츰 떨어지는 레거시(legacy)6 데이터베이스 디자인에 있어 일반적인 문제

이다.

문서화의 필요성은 곧 리팩토링의 필요성을 반영한다

테이블, 컬럼 혹은 저장 프로시저를 설명하기 위한 문서화의 필요성을 발견했다면, 그

것은 스키마의 일부를 좀 더 이해하기 쉽게 리팩토링할 필요가 있음을 알려주는 좋은

표적이다. 아마도 간단한 이름 변경만으로 문서의 몇몇 절을 피할 수 있을 것이다. 명

확한 디자인은 문서화의 필요를 더 줄여준다.

3.7 외부 액세스 프로그램을 리팩토링한다

데이터베이스 스키마가 변경되면, 그 스키마의 변경된 부분에 액세스하는 기존의 외부 프

로그램을 종종 리팩토링해야 할 것이다. 2장 ‘데이터베이스 리팩토링’에서 배웠듯이 몇가지,

즉 레거시 애플리케이션과 영속성 프레임워크(persistence framework), 데이터 복제 코드 및 리

포팅 시스템이 포함될 것이다.

몇몇 좋은 책은 외부 액세스 프로그램에 대한 효과적인 리팩토링 지침을 제공한다.:

▒ Refactoring: Improving the Design of Existing Code (Fowler 1999)은 이 주제

의 고전이다.

▒ Working Effectively with Legacy Code (Feathers 2004)은 수 년간 조직 내에

서 존재해 왔던 레거시 시스템을 어떻게 리팩토링해야 할 지를 설명한다.

▒ Refactoring to Patterns (Kerievsky 2004)은 일반적 디자인과 아키텍처적 패턴

을 구현하도록 코드를 조직적으로 리팩토링하는 방법을 설명한다.

6.  Legacy: 현재 기술보다 이전의 언어(language)와 기술 또는 플랫폼(platform)으로 구축된 애플리케이션이나, 데이터베이스를 말할 때

사용한다.

Page 84: 리팩토링 데이터베이스 : 진화적 데이터베이스 디자인

52

The Process of Database Refactoring _3

많은 응용 프로그램이 데이터베이스에 액세스한다면 그것들 중 일부는 변경된 스키마를 사

용하도록 업데이트되지 않았거나, 아직까지 소스 코드를 변경할 개발 팀 조차 배정되지 않

았을 수도 있다는 것에 대한 위험을 감수해야 한다. 이것은 누군가 해당 애플리케이션의

업데이트에 대한 책임을 져야할 뿐만 아니라, 또한 비용에 대한 무거운 부담도 짊어져야

함을 암시한다. 희망 사항이지만, 다른 팀이 이런 외부 프로그램에 대한 책임을 가질 수도

있다. 그렇지 않으면 여러분의 팀이 요구된 변경을 수행할 책임을 받아들여야 한다. 다른

시스템을 변경하는 요구 사항을 둘러싼 정치적 도전이 멀고 무겁게 느껴져서 기술적 도전

을 막아버리는 것을 발견할 때마다 좌절감을 느낀다.

지속적인 개발을 위한 목표

이상적인 조직은 그들의 모든 애플리케이션을 시간에 걸쳐 서서히 발전시켜 나가고,

일정한 기준으로 배포하는 등 지속적으로 작업해 간다. 이것이 비록 복잡하게 보이고,

실제 그렇다고 하더라도, 조직 내의 시스템이 변화의 요구에 충족하도록 IT 부서가 적

극적으로 노력하지 않아도 되는 것인가? 이런 환경에서는 데이터베이스에 액세스하는

모든 애플리케이션은 일정한 기준으로 서서히 발전되어 가며, 그에 따르는 스키마의

변경사항을 애플리케이션에 적용하기 때문에 상대적으로 짧은 과도기를 가질 수 있다.

이렇게 외부 프로그램을 업데이트할 아무런 지원도 없을 경우 어떻게 해야 하나? 선택할

수 있는 두가지 기본 전략이 있다. 첫째, 데이터베이스 리팩토링을 하고 수십 년간의 과도

기를 둔다. 이 방법으로 변경하지 않은 외부 프로그램은 여전히 동작한다; 그렇지만 다른

애플리케이션은 개선된 디자인을 액세스할 것이다. 이 전략은 양쪽 스키마를 지원하는 테

스트 발판 코드(scaffolding code)가 오랫동안 남아 있어 데이터베이스 성능을 저하시키고 데이

터베이스를 어지럽게 하는 유감스러운 손실을 가져다준다. 두 번째 전략은 리팩토링을 아

예 하지 않는 것이다.

Page 85: 리팩토링 데이터베이스 : 진화적 데이터베이스 디자인

53

3_ 데이터베이스 리팩토링 프로세스

3.8 회귀 테스트를 실행한다

리팩토링 구현의 일부로서 그것이 작동하고 있다는 것을 보장하는 테스트를 한다. 앞서 지

적했듯이 테스트를 조금하고, 변경을 조금하고, 다시 테스트를 조금하는 등으로 리팩토링

이 완료될 때까지 계속 테스트를 수행한다. 테스트 활동은 가능한 한 자동으로 수행되어야

한다. 데이터베이스 리팩토링의 중요한 이점은, 리팩토링이 작은 변경사항을 표현하기 때

문에 테스트가 중도에 깨어졌을 때도 단지 그 변경사항만을 수정하면 된다.

3.9 작업한 내용에 대해 버전 관리를 한다.

데이터베이스 리팩토링이 성공적으로 완료되었을 때는 버전관리 도구로 체크하여 모든 작

업을 형상관리(CM) 시스템하에 두어야 한다. 소스 코드를 다루는 것과 동일한 방법으로

데이터베이스 지향적 아티팩트 또한 다루도록 한다. 버전 관리가 필요한 아티팩트는 다음

과 같다.

▒ 생성한 스크립트

▒ 테스트 데이터와(혹은) 생성한 코드

▒ 테스트 케이스

▒ 관련 문서

▒ 모델

3.10 리팩토링이 끝났음을 알린다.

데이터베이스는 공유 자원이다. 여러 애플리케이션 팀에 의해서는 아닐지라도 최소한 여러

분의 애플리케이션 개발팀 내에서는 공유될 것이다. 그러므로 데이터베이스 리팩토링이 수

행되었다면 이해 관계자들과 커뮤니케이션이 필요하다. 리팩토링 생명 주기의 초기에 팀의

다음번 기립 회의(standup meeting)에서 변경사항을 알리는 것처럼, 간단히 말할 수 있도록 팀

Page 86: 리팩토링 데이터베이스 : 진화적 데이터베이스 디자인

54

The Process of Database Refactoring _3

내에서 변경사항을 서로 커뮤니케이션할 필요가 있다. 다중 애플리케이션 데이터베이스 환

경에서 변경사항은 다른 팀과 반드시 커뮤니케이션해야 한다. 특히 리팩토링을 사전 프로

덕션 테스트 환경으로 승급시키기 위해 결정할 때는 더더욱 그렇다. 이런 커뮤니케이션은

데이터베이스 변경사항을 알리는 데 사용되는 특별한 내부 메일링 리스트의 간단한 이메일

수도 있고 정기 프로젝트 상태 보고서의 한 항목일 수도 있으며, 혹은 운영 데이터베이스

관리그룹의 형식적인 보고서일 수도 있을 것이다.

발표의 중요한 측면은 관련된 문서에 대한 최신 상태로의 문서 업데이트이다. 이 문서는

다른 팀들이 데이터베이스 스키마가 어떻게 발전돼 왔는지 알아야 하기 때문에 리팩토링

을 승급하거나 배포할 동안 매우 중요하다(4장 참조). 간단한 접근방법은 수행된 변경사항

을 요약한 데이터베이스 릴리즈 노트를 개발하여 각 데이터베이스 리팩토링 순서대로 리스

트하는 것이다. 우리의 리팩토링 예제는 이 리스트에서 ‘163: Customer.Balance 컬럼을

Account 테이블로 옮기기’처럼 나타난다. 이런 릴리즈 노트는 기업 관리자에 의해 요구될

것이며 그들은 관련된 메타 데이터를 업데이트할 것이다.(더 좋은 것은, 여러분의 팀이 리

팩토링 일환으로 이 같은 메타 데이터를 업데이트하는 것이다)

데이터베이스의 물리 모델(PDM)도 업데이트해야 할 것이다. PDM은 데이터베이스 스키

마를 설명하는 기본 모델(primary model)이고 보통 애플리케이션 개발 프로젝트에서 생성되

어 ‘유지’되는 몇몇 모델 중 하나로서 가능한 반드시 최신 정보로 업데이트되어야 한다.

너무 조급하게 데이터 모델을 발표하지 말라

객체와 데이터베이스 스키마는 개발에 진화적인 접근방법을 사용함으로, 그 디자인이

시간이 지나감에 따라 드러나기 때문에 초기에는 변동사항이 있을 것이다. 이 같은 초

기 변동사항 때문에 물리적 데이터모델을 업데이트하기 전에 스키마의 새로운 일부가

안정화될 때까지 기다려야 한다. 이것은 문서화에 들어가는 노력을 줄여줄 뿐만 아니

라 해당 데이터베이스 스키마에 연관된 다른 애플리케이션 팀에 미치는 영향력을 최소

화한다.

Page 87: 리팩토링 데이터베이스 : 진화적 데이터베이스 디자인

55

3_ 데이터베이스 리팩토링 프로세스

3.11 무엇을 배웠나

데이터베이스 리팩토링의 고된 일은 개발 샌드박스 내에서 개발자와 DBA가 짝을 이룸으

로서 완료된다. 첫 번째 단계는 데이터베이스 리팩토링이 필요한 것인지 확인하는 것이다

-혹시 리팩토링 수행에 들어가는 비용이 현재 이득보다 더 비싸지는 않는지, 혹은 현재 스

키마가 특정 이슈에 대하여 가장 좋은 디자인은 아닌지 확인한다. 만약 리팩토링이 필요하

다면 작업을 완료하는데 가장 적합한 리팩토링을 선택한다. 다중 애플리케이션 환경에서는

대부분의 리팩토링이 과도기 동안 원본과 새로운 스키마를 동시에 모두 지원하기를 요구하

며, 애플리케이션이 재 배포되기까지 스키마의 일부에 애플리케이션이 액세스할 수 있도록

충분한 기간을 가져야 한다. 리팩토링을 구현하기 위해서는 리팩토링으로 발생할 수 있는

어떠한 중단이든지 더 쉽게 찾을 수 있도록 테스트 우선 접근방법론(Test-First Approach)을

사용해야 한다. 데이터베이스 스키마를 변경해야 하고 잠정적으로 관련된 소스데이터를 마

이그레이션해야 하며, 그 후 스키마에 접근하는 외부 프로그램을 변경해야 한다. 수행하는

모든 작업은 버전 관리가 되어야 하며 리팩토링이 개발 환경 내에서 구현된 후에는 팀동료

와 특별히 스키마의 변경사항에 대해 알아야 할 적절한 외부 팀에게 무엇을 어떻게 리팩토

링했는지 알려주어야 한다.