Page 1


서문

|

시작하며 책을 보는 사람 중에는 왜 이제 와서 관계형 모델에 관한 책을 읽지 않으면 안 되는 거야? 라고 생각하는 사람이 있을지도 모른다. 관계형 모델에 관한 책을 읽지 않으면 안 되는 이 유를 한마디로 말하면 「SQL은 어렵기 때문」이다. 관계형 데이터베이스(이하 RDB)가 이 세상에 나오고 오랜 시간이 흘렀지만 필자는 아직 도 많은 사람이 RDB를 잘 다루지 못한다고 생각한다. RDB를 잘 다루려면 관계형 모델에 관한 이해가 필수이다. 그러나 많은 사람이 관계형 모델에 관해 올바르게 이해하고 있다고 는 말할 수 없다. 어떻게 데이터베이스(이하 DB)를 설계하면 좋을지 또는 어떻게 DB에서

SQL을 사용해 검색하는지 등과 같은 내용은 관계형 모델을 이해하지 않으면 알지 못한다. 그냥 맹목적으로 설계하거나 SQL을 작성하는 것만으로는 RDB를 잘 다루고 있다고는 결 코 말할 수 없다. 관계형 모델은 오래됐으며, 새로운 주제다. RDB가 등장하고 수십 년이 지났음에도 여전히 많은 사람이 이해하고 있다고는 말하기 어렵고 관계형 모델 자체에 대해서도 제대로 설명 되지 않고 있다고 보인다. 거리에 넘쳐나는 기술서는 SQL에 관해 쓴 책은 많지만, 관계형 모델이 무엇인지 이를 어떻게 사용할 것인지에 관해 쓴 책은 거의 없다. 게다가 알기 쉽게 요약해서 정리한 책은 아예 없다. 이것이 이 책을 세상에 내보내게 된 동기이다. 관계형 모델을 좀처럼 이해하기 어려웠던 배경에는 컴퓨터의 리소스나 RDB 제품이 가진 기능에 제한이 있었던 것을 원인으로 들 수 있다. 관계형 모델을 구현하려고 해도 기술적 인 벽이 가로막고 있다. 그러나 시대가 바뀌었다. 무어의 법칙 덕분에 고성능 CPU를 저렴 하게 손에 넣을 수 있게 됐고, 각종 RDB 제품 또한 개발에 전념함으로써 기능이 확충됐다. 드디어 관계형 모델을 다룰만한 토대가 갖춰졌다고 말할 수 있다.

V


VI

|

서문

현재 대부분 서버 응용프로그램의 개발 현장에서 RDB가 사용되고 있다. SQL이 가장 많 이 사용되는 프로그래밍 언어의 하나인 것은 의심할 수 없는 사실이다. 그러나 SQL이 상당 히 많이 사용되고 있지만, 최근에는 NoSQL이나 ActiveRecord가 대두되고 있기도 하며, 이전에 비해 경시되는 경향도 있다고 생각된다. 하지만 이러한 경향과는 반대로 SQL을 잘 쓰는 능력은 매우 중요하다. 응용프로그램 개발의 성공 여부는 어떻게 RDB를 잘 활용하는 가, 즉 어떻게 세련되게 SQL을 작성하느냐에 달려 있다고 해도 과언이 아니다.

SQL은 수십 년 동안 RDB의 질의 언어로써 사용돼 왔다. 왜 그렇게까지 오랜 시간 동안 사 용되고 있을까 생각해 보면 역시 편리하기 때문이 아닐까 생각된다. SQL만큼 짧게 작성해 많은 처리를 컴퓨터에게 수행하게 할 수 있는 강력한 언어는 SQL 외에는 없을 것이다. 이처럼 매우 편리하고 강력한 SQL이지만 잘못 사용하면 불필요한 작업을 하게 될 수도 있 다. 사용법을 잘못 알고 있으면 가끔은 복잡하고 비효율적인 SQL 문을 작성하게 된다. 이 른바 「스파게티코드」가 아닌 「스파게티SQL」이 되어 버린다. 응용프로그램이 커질수록 성능이 더욱 중요하게 됐다. 스파게티SQL은 성능에 천적이다. 효율이 높지 않으면 당연히 그 SQL 자체의 응답성은 저하되고 그 부하는 시스템 전체의 처 리량을 저하시키게 될 것이다. SQL은 유용하지만 그만큼 잘못 사용했을 때의 영향도 크다 는 위험 요소도 있다. 이 책은 RDB 초심자를 위한 입문서는 아니다. DB 응용프로그램을 개발한 경험이 있는 경 험자를 대상으로 하고 있다. 이미 기본적인 SQL 문의 의미를 이해하고 있는 사람이 SQL에 대한 지식을 더욱 심화하기 위한 것을 목표로 하고 있다. 그리고 조금이라도 많은 사람이

RDB를 올바르게 사용하지 않아서 생기는 비극을 피하는 것을 목적으로 하고 있다.


서문

|

주제는 SQL과 릴레이션(관계) 모델로 시작해 DB 설계나 응용프로그램 개발에 이르기까 지 이론과 실습을 함께 설명한다. SQL을 다시 공부하고 싶다고 생각하고 있거나 아직은 관 계형 모델에 대해서 잘 모르는 중급자가 주요 대상이다. RDB에 대한 일반적인 내용이 주 제이며 특정 제품에 대한 설명은 하지 않는다. 또한, 이 책에서는 SQL의 자세한 문법에 관 해서는 다루지 않는다. 이미 독자들이 어느 정도 SQL을 이해하고 있다는 전제로 이야기하 므로 SQL 문법을 자세히 알고 싶다면 다른 책을 찾기 바란다. 자, 지금이야말로 RDB를 잘 다룰 기회다. 이 책을 다 읽고 나면 분명 RDB에 대한 견해가 지금까지와는 다르게 보일 것이다. 2015년 1월 오쿠노 미키야(奥野幹也)

VII


VIII

|

목차

01

SQL과 관계형 모델

1.1 SQL이란 관계형 모델을 모르더라도 SQL을 쓸 수 있다?

2 2 3

RDB는 관계형 모델을 바르게 구현할수록 더욱 진가를 발휘한다! 1.2 관계형 모델

3 4

릴레이션(관계)의 정의

5

집합과 관계형 모델

7

집합이란

7

관계형 모델과 NULL

8

유한집합과 무한집합

9

릴레이션의 연산

9

제한(Restrict)

10

프로젝션(Projection)

10

확장(Extend)

12

속성명 변경(Rename)

13

합집합(Union)

14

교집합(Intersect)

15

차집합(Difference)

16

곱집합(Product)

17

결합(Join)

17

클로저(closure) 성질

20

관계형 모델의 데이터 형식

20

1.3 SQL에서 릴레이션 조작

22

SELECT의 기본형

22

INSERT(삽입)

25

DELETE(삭제)

26

UPDATE(갱신)

27


목차

1.4 SQL에는 있고 관계형 모델에는 없는 것

|

28

요소의 중복

28

요소 사이의 순서

29

릴레이션의 갱신

29

트랜잭션

29

스토어드 프로시저

30

NULL

30 30

1.5 요약

02

술어논리와 관계형 모델

2.1 술어논리와 관계형 모델

32 33

명제

33

명제논리

34

동어반복과 정리

35

명제논리와 공리계

37

명제논리의 한계와 양화논리(양한정)

40

정량자와 술어논리

41

정량자와 함께 사용하는 속박변수

42

술어논리와 집합론

43

도메인

47

1차 술어논리

47

2차 술어논리

47

릴레이션의 참의 형태

48

폐쇄 세계 가정

49

모순된 DB는 쓸모없다

50

IX


X

|

목차

2.2 릴레이션의 연산과 술어논리

51

제한(Restrict)

51

곱집합(Product)

51

결합(Join)

52

교집합(Intersect)

54

합집합(Union)

55

차집합(Difference)

56

프로젝션(Projection)

56

속성명 변경(Rename)

58

확장(Extend)

58 60

2.3 요약

03

SQL과 관계형 모델

61

3.1 왜 DB 설계가 중요한가?

61

3.2 정규화

62

관계형 모델을 보완하는 이론

62

변칙을 방지할 수 있다

63

3.3 정규형

65

정규형의 종류

65

제1 정규형(1NF)

66

후보키와 슈퍼키

73

함수 종속성(FD)

74

제2 정규형(2NF)

75

제3 정규형(3NF)

77

보이스코드 정규형(BCNF)

79

3.4 요약

81


목차

04

정규화 이론(두 번째) - 결합 종속성

4.1 결합 종속성(JD)

|

82 82

결합 종속성은 무손실 분해가 가능

83

함수 종속성은 결합 종속성의 일종이다

83

암시적인 결합 종속성

84

키가 아닌 속성과 결합 종속성

85

4.2 결합 종속성에 의한 정규화(4NF~6NF)

86

제4 정규형(4NF)

86

제5 정규형

88

제6 정규형(6NF)

91 93

4.3 요약

05

릴레이션의 직교성

5.1 릴레이션의 직교성과 중복

94 95

레플리카

95

같은 형태의 릴레이션

95

제목 일부만 같은 릴레이션

96

5.2 릴레이션 직교화를 위한 전략

98

정규화

98

속성(칼럼)의 이름 통일하기

98

응용프로그램의 정합성

99

5.3 중복을 해결해 얻는 이점

100

변칙을 막을 수 있다

100

필요한 데이터가 어디에 있는지 명확해진다

101

쿼리의 작성이 선언적이 된다

101

불필요한 무손실 분해는 필요 없다

101

XI


XII

|

목차

복잡한 제약은 필요 없다

104

응용프로그램의 코드에 낭비가 없어진다

105

성능이 향상된다

105 106

5.4 요약

06

도메인 설계 전략

6.1 도메인

107 108

도메인이란

108

집합의 요소

108

6.2 도메인 설계 전략의 개요

109

모든 것은 자의적인 선택

109

응용프로그램의 필요성으로 생겨난다

110

데이터의 본질을 파악한다

111

속성(칼럼)의 이름

113

6.3 ID를 설계한다는 개념

113

현실 세계의 물체나 개념을 나타내는 수단

113

관계형 모델의 키

118

의미가 있는 ID

119

ID의 결함이 미치는 영향

120

색, 길이, 무게 등의 성질을 나타내는 속성

121

6.4 SQL로 도메인 표현

122

적절한 데이터형 선택

122

술어를 제약으로 표현

122

도메인을 테이블로 표현

123

6.5 요약

123


목차

07

NULL과의 싸움

|

125 126

7.1 NULL NULL이란

126

3치논리(3VL)

127

3치 논리의 한계

130

NULL은 폐쇄 세계 가정에 반한다

131

옵티마이저에 대한 폐해

132

7.2 NULL의 대책

133

테이블을 정규화한다

133

잘못된 NULL 대책

134

COALESCE 함수

136

빈 문자열의 처리

137

NULL을 사용해도 좋을 때

138 139

7.3 요약

08

SELECT를 공략하자

8.1 SELECT는 SQL의 심장부

140 141

SELECT의 본질

141

SELECT의 기본 구조

142

8.2 SELECT의 다양한 모습

143

집계함수

144

서브쿼리

149

152

UNION

153

조합은 자유

153

XIII


XIV

|

목차

8.3 관계형이 아닌 조작

153

관계형 조작의 복습

154

정렬(sort)

155

명시적으로 정의되지 않은 칼럼

155

스토어드 함수(사용자 정의 함수)

155

관계형이 아닌 조작의 취급법

157

8.4 들여쓰기로 SELECT 문장을 읽기 쉽게 들여쓰기 규칙

159 160

8.5 요약

09

158

이력 데이터와 친해지기

9.1 이력 데이터의 문제점

161 162

세상은 이력 데이터가 넘쳐난다

162

이력과 관계형 모델의 상성 문제

163

이력 데이터의 구체적인 예

163

이력 데이터의 어떤 것이 문제가 되는가?

164

9.2 이력 데이터에 대한 해결책

167

릴레이션을 나눈다

168

가장 간단한 분할 방법

168

중복행을 허용

170

대리키

171

미래의 가격을 어떻게 해야 할까?

172

9.3 이력데이터의 안티 패턴

174

플래그 사용

174

절차형으로 구현하자

176

9.4 요약

177


목차

10

그래프에 맞서다

|

179

10.1 그래프의 구조

180

노드, 에지

180

인접

181

차수

181

보행, 트레일, 길

181

다중 에지

182

루프

182

닫힌 보행

182

연결

182

부분 그래프

182

컷세트, 브리지

183

에지의 방향과 가중치

183

그래프를 응용한 예

183

10.2 그래프의 종류

184

일반 그래프

184

단순 그래프

184

연결 그래프/비연결 그래프

185

완전 그래프

185

정규 그래프

186

평면 그래프

186

유향 그래프/무향 그래프

186

가중 그래프

187

트리(나무)

187

10.3 SQL과 그래프의 상성 문제

187

그래프에 대한 쿼리

188

무향 그래프를 표현할 수 있는가?

188

유향 그래프를 이용한 표현

189

릴레이션 관점에서 모델을 이해하자

190

그래프에 대한 쿼리

192

XV


XVI

|

목차

절차형에 의한 해법

194

그래프 DB

195

그 외의 문제

195 196

10.4 트리 트리는 그래프의 일종

197

인접 리스트 모델

198

경로 열거 모델

200

중첩 집합 모델

202

클로저 테이블

205

트리와 SQL에 관한 고찰

207 207

10.5 요약

11

인덱스 설계 전략

209

11.1 인덱스의 동작

209

RDB의 인덱스

209

인덱스의 왼쪽과 검색 범위

211

보조 인덱스의 갱신

212

11.2 인덱스의 종류

213

해시 인덱스

213

전문 검색 인덱스

213

R트리 인덱스

215

함수 인덱스

218

비트맵 인덱스

218

11.3 파티셔닝

219

파티셔닝이란

220

파티셔닝이 적합한 경우

221

파티셔닝과 고유성 제약

222

파티셔닝에 관한 일반적인 오해

223


목차

11.4 관계형 모델과 인덱스

|

223

인덱스는 관계형 모델의 일부가 아니다

224

정규화와 인덱스

225

11.5 지령: 최적의 인덱스를 찾아라!

226

필요한 인덱스

226

인덱스의 엑세스 특성

227

인덱스가 사용되는 구문

227

최적의 인덱스를 찾기 위한 전략

233 237

11.6 요약

12

웹 응용프로그램을 위한 데이터 구조

239

12.1 캐시라는 개념

240

장점/단점

240

DB 응용프로그램에서의 캐시

241

캐시는 어디까지나 캐시

241

캐시로 사용하기 위한 요건

241

캐시할 만한 데이터의 종류

242

12.2 캐시의 구축 방법

243

NoSQL을 캐시로 사용

243

테이블을 캐시로 사용

246

집계 테이블

247

조인(JOIN)된 데이터

251

태그

253

12.3 스케일 아웃

261

리플리케이션(복제)

262

샤딩

263

12.4 요약

266

XVII


XVIII

|

목차

13

리팩터링 최적의 해결책

13.1 리팩터링

267 268

DB 리팩터링은 어려운 작업

268

다양한 응용프로그램에 대한 DB 환경

269

왜 리팩터링이 필요한가?

270

리팩터링의 절차

270

스키마의 이행 기간

271

반복적인 리팩터링

272

13.2 리팩터링의 종류

275

인덱스의 추가, 삭제

276

칼럼 이름 변경

276

NOT NULL 제약의 도입

278

기본키의 정의 변경

278

무손실 분해

279

테이블의 수직 분할과 통합

280

13.3 리팩터링을 위한 모범 사례

284

정규화와 직교성

284

칼럼이 아닌 테이블을 추가

284

SELECT *을 사용하지 않는다

285

응용프로그램을 소결합으로

286

13.4 요약

287


목차

14

트랜잭션의 본질

14.1 트랜잭션

|

288 289

트랜잭션의 기능

289

트랜잭션의 키, 스케줄

291

「데이터의 정확성」의 정의

292

스케줄러의 성능

292

14.2 트랜잭션의 특징

293

ACID란?

293

다양한 비정상 상태

295

갱신 분실

295

스케줄과 잠금

299

교착 상태(Dead Lock)

301

트랜잭션 격리 수준

302

MVCC

303

크래시 복구

305

14.3 트랜잭션과 데이터 모델의 융합

306

관계형 모델과 ACID의 「C」

306

관계형 모델과 이상 현상

307

정규화와 직교성

308

제약

308

14.4 요약

312

마치면서

313

XIX


01 SQL과 관계형 모델

이번 장에서는 관계형 모델의 개요에 관해서 설명한다. SQL이란 무엇인지, 그리고 관계형 모델이 어떤 것인지에 대한 틀을 잡는 것이 목적이다. 또한, SQL이 관계형 모델에 어떻게 대입되는가? 또는 어떻게 다른가?에 관해서도 소개한다.

1.1 SQL이란 SQL이란 관계형 데이터베이스(이하 RDB)에 질의를 하기 위한 언어다. 따라서 관계형 모 델1 이 SQL의 기반이 된다는 것은 의심할 수 없는 사실이다. 그러나 애석하게도 SQL 구문 이나 문법만 봐서는 관계형 모델이 어떤 것인지는 알 수 없다.

1 관계형 모델은 1.2절에서 설명한다.


01 _ SQL과 관계형 모델

관계형 모델을 모르더라도 SQL을 쓸 수 있다? 필자는 RDB 초보 시절에 SQL 구문부터 공부하기 시작했다. 아마도 현재 활동하고 있는 데이터베이스(이하 DB) 엔지니어의 대부분은 SQL 구문부터 공부하지 않았을까 생각된다. 맞고 틀리고는 제쳐놓고 구문을 알면 SQL을 쓸 수 있다. 그리고 SQL을 사용하다 보면 어 떤 SQL을 쓸 때 쿼리가 효과적인지도 자연스럽게 알게 된다. 예를 들어, 테이블에 추가할 인덱스를 어떻게 할 것인지 또는 상관 서브 쿼리를 JOIN으로 바꾼다든지 등의 테크닉처럼 말이다. 이런 테크닉이 쌓이면 관계형 모델을 몰라도 딱히 불편함 없이 쓸 수 있다. 그래서 「SQL은 알아도 관계형 모델은 모른다」는 상황이 생긴다. 이런 사람들이 생각보다 꽤 많을 것이라고 생각한다. 물론 관계형 모델을 모르는 게 좋을 리는 없다. 관계형 모델에 대한 지식이 부족하면 언젠 가는 벽에 부딛히는 날이 오기 때문이다. 진정으로 능력 있는 DB 엔지니어를 목표로 한다 면 관계형 모델은 필수 과목이다. 그러므로 SQL을 어느 정도 알고 있는 상태에서 관계형 모델에 관해서 공부하도록 하자. 관계형 모델에 대해 알면 알수록 여러분은 다음과 같이 생각할 것이다. 「SQL과 관계형 모델이 실제로 아주 닮아있지 않네...?(짐작한 것보다 많이 다르군……)」 지금까지 사용해 온 SQL은 도대체 뭐였을까?라고 생각할지도 모른다. 사실은 SQL이 능숙 한 사람도 관계형 모델을 이해하기는 쉽지 않다.

RDB는 관계형 모델을 바르게 구현할수록 더욱 진가를 발휘한다! 왜 SQL에 관한 지식만으로는 부족하고 관계형 모델에 관해서 알아야만 하는 것일까?

SQL은 관계형 모델을 기반으로 한 질의 언어이지만 관계형 모델을 충실하게 재현하지는 않는다. SQL은 매우 유연성이 높게 설계된 언어이므로 관계형 모델에 맞게 사용할 수도 있 고, 반대로 전혀 다르게 사용할 수도 있다. 후자의 경우라면 사용할 때 주의해야 하지만 관 계형 모델을 모른다면 관계형 모델에서 벗어나고 있는지조차도 판단할 수 없다.

3


4

원리부터 배우는 관계형 데이터베이스 실전 입문

RDB에 관해 대부분이 잘못 생각하고 있는 것 중의 하나는 DB를 단순한 데이터의 그릇이 라고 생각하는 것이다. 인덱스만 잘 타면 빠르게 엑세스 할 수 있으므로 데이터베이스 설계 (이하 DB 설계), 즉 개별 테이블 설계와 DB의 전체적인 통합성은 어떻게 되든 상관없다고 생각한다. 물론 그런 일은 불가능하다. 관계형 모델을 모르면 자신도 모르는 사이에 매우 비효율적인 쿼리를 사용하게 될 것이다.

RDB를 관계형 모델에 맞지 않게 사용한다는 것은 오프로드를 포뮬러카(경주용 자동차)로 달리는 것과 같다2 . 어떠한 도구라도 잘못 사용하면 본래의 성능을 발휘할 수 없는 것은 두 말하면 잔소리다.

SQL을 잘못 사용하면 단순히 성능을 발휘할 수 없을 뿐만 아니라 SQL 문이 복잡하고 이상 해진다. SQL은 관계형 모델을 기반으로 설계돼 있으므로 관계형 모델에 따른 연산이 가장 적합하다. 복잡하고 이상한 SQL 문은 가독성도 나쁘고 버그의 원인이 될 것이다. DB 응용 프로그램3 을 유지보수 할 때도 관계형 모델에 관해서 이해하는 것이 중요하다. 관계형 모델이란 어떤 것인가? SQL부터 공부를 시작한 사람에게는 신선한 주제일지도 모 른다. 그러면 지금부터 관계형 모델에 관해서 좀 더 자세히 살펴보자.

1.2 관계형 모델 이 책에서는 자세한 역사에 관한 이야기는 다루지 않는다. 대신 바로 본질에 관해 이야기하 고자 한다. 관계형 모델은 실제 세계의 데이터를 「관계」라는 개념을 사용해 표현한 데이터 모델이다. 데이터 모델이라는 말에 ERD(Entity Relationship Diagram)와 같은 모델링 툴을 떠올 릴지도 모르지만, 실은 ERD와 관계형 모델은 아무런 관계가 없다. 「ERD야말로 관계형 모 델을 구현하는 데 필요한 툴이다」라는 설명을 많이 볼 수 있지만, 이것은 잘못된 생각이다.

2 포뮬러카는 서킷에서는 뛰어난 성능을 발휘하지만 오프로드에서는 달리는 것조차 마음대로 되지 않을 것이다. 3 여기에서는 DB를 사용하는 것을 전제로 구축된 응용프로그램을 말한다.


01 _ SQL과 관계형 모델

이처럼 데이터 모델이라고 하면 설계를 의미하는 모델링으로 생각하는 사람들이 많다. 하 지만 관계형 모델이 나타내는 데이터 모델은 설계의 의미가 아니고 “데이터를 어떻게 표현 할까”라는 개념의 의미다. 「○○라는 개념을 사용해 데이터를 표현해 주세요」라고 정하는 것이 데이터 모델이며 관계형 모델은 그중에 하나라고 할 수 있다. 최근에는 KVS(Key-Value Store)가 많이 사용되고 있는데, KVS처럼 키와 그에 해당하는 값의 형태로 데이터를 표현하는 것도 데이터 모델의 하나다. 관계형 모델은 이와는 다른 데 이터의 표현 방법이다. 이러한 관계형 모델을 이해하는 데 가장 중요한 개념이 관계(릴레이션)다.

릴레이션(관계)의 정의 릴레이션4 이란 무엇일까? 가장 일반적인 실수는 「테이블 사이의 관계」라고 생각하는 것이 다. 계속해서 말하지만 테이블 사이의 관계를 (ERD 등을 사용해) 디자인하는 것이 관계형 모델이라고 오해하는 사람들을 꽤 볼 수 있다. 만약 여러분이 이런 오해를 하고 있다면 지 금 당장 생각을 바꾸자. 단도직입적으로 대답하면 사실 SQL에 있어 릴레이션에 해당하는 것은 테이블이다. 관계형 모델에서 릴레이션의 정의는 다음과 같다. 릴레이션은 제목(Heading)5 과 본체 (Body)로 구성돼 있다. 제목은 속성(Attribute)이 n개6 모인 집합이며, 이 속성은 이름과 데이터 형으로 되어 있 다. 본체는 속성값의 집합인 행 또는 영어로 말하면 튜플(tuple)의 집합이다7 . 튜플에 포함된 속성값은 이름과 데이터 형이 제목에서 지정한 것과 서로 일치하지 않으면 안 된다. 제목에서 정의하지 않은 속성이 튜플에 존재하거나, 반대로 제목에는 포함된 속 성이 튜플에는 존재하지 않는 경우는 규칙 위반이다8 . 바꿔서 말하면 릴레이션이란 튜플의

4 이 책에서는 관계라고 말하지 않고 릴레이션이라고 한다. 관계라는 단어는 다른 문맥에서도 자주 사용되므로 혼란을 피하기 위해 서다. 5 (역자주) 데이터베이스의 스키마로 칼럼(속성)의 집합을 말한다. 6 n은 0 이상의 정수다. 7 릴레이션과 마찬가지로 쌍이라는 단어는 다른 문맥에서 사용되므로 이 책에서는 튜플이라고 표현한다. 8 만약 그와 같은 튜플이 포함돼 있다면 경우 그 집합은 릴레이션이라고 할 수 없다.

5


6

원리부터 배우는 관계형 데이터베이스 실전 입문

집합이고, 튜플은 모두 같은 n개의 속성값의 집합으로, 데이터 구성이 서로 같다. 그림 1.1 은 릴레이션 관계를 그림으로 표현한 것이다. 그림 1.1에서는 국가, 국가번호, 지역이라는 3개의 속성으로 릴레이션이 구성돼 있다. 엄 밀히 말하면 튜플의 집합은 릴레이션의 본체이며 원래 의미는 본체와 제목의 쌍을 가진 관 계라고 하지만 문맥에 따라서는 제목이 포함돼 있거나 포함되지 않기도 한다. 그 부분은 적 절하게 바꿔서 이해해야 하며 이 책에서도 마찬가지다. 튜플과 속성을 SQL에서는 각각 행(로우)과 열(칼럼)이라고 한다9 . 그런데 관계형 모델과

SQL에는 각각에 맞는 개념이 있는데 왜 다른 이름으로 부르는 것일까? 사실 명칭이 다른 것은 이것들이 개념은 같지만, 성질이 다르기 때문이다. 다른 성질의 것, 즉 다른 개념을 같은 이름으로 부르지는 않는다. 어떻게 다른가에 대해서는 이 책에서 차차 설명한다. 표 1.1에서 관계형 모델과 SQL에 대한 각 객체를 정리하고 있다.

제목 국가/문자열

국가번호/정수

지역/문자열

본체

국가: 대한민국, 국가번호: 82, 지역: 아시아

국가: 오스트리아, 국가번호: 61, 지역: 오세아니아

그림 1.1 릴레이션의 예

9 이 책에서는 열을 칼럼이라고 한다.

국가: 일본, 국가번호: 81, 지역: 아시아

국가 : 미국, 국가번호: 1, 지역: 북미

국가: 카메룬, 국가번호: 237, 지역: 아프리카

국가: 스웨덴, 국가번호: 46, 지역: 유럽


01 _ SQL과 관계형 모델

표 1.1 관계형 모델과 SQL

관계형 모델

SQL

릴레이션

테이블

튜플

속성

칼럼

집합과 관계형 모델 조금 전부터 계속해서 「집합」이라는 단어가 나오고 있는데 집합의 성질에 관해 좀 더 자세 하게 살펴보자.

집합이란 집합은 수학에서 사용되는 개념으로 그 이름에서 알 수 있듯이 물건의 모임을 표현하는 개 념이다. 집합에 포함된 각 물건을 요소나 원소(Element)라고 한다. 요소로 사용될 수 있다 면 어떤 것이든지 상관없다. 숫자나 문자뿐 아니라 모든 것을 요소로 취급할 수 있다. 요소 에는 특별한 제약이 없으며 물건의 모임을 처리하기 위한 범용적인 구조로써 집합을 사용 할 수 있다. 릴레이션도 집합의 한 종류이므로 집합이 가진 특성은 릴레이션에도 응용할 수 있다. 그림 1.2는 집합을 간략하게 나타낸 그림이다. 이 그림에서는 집합에 6개의 숫자가 요소로 포함돼 있다. 집합의 요소는 어떤 성질이든 상관없지만 충족해야 할 조건이 몇 가지 있다. 여기서는 두 가지 조건을 생각해보자. 첫 번째 조건으로 어떤 요소가 집합에 포함돼 있는지 불확정한 요소 없이 판정할 수 있어야 한다. 예를 들어 숫자로 이뤄진 집합 N이 있다고 하면 1이라는 숫자가 N에 포함돼 있는지 확실하게 판단할 수 있어야 한다. 바꿔서 다시 얘기하면 무엇인지 모르는 미지의 요소는 집 합에 포함될 수 없다는 의미다. 예를 들어 그림 1.2에서 「1은 집합에 포함되었나?」 「3은 집 합에 포함되었나?」 등의 질문에 명확하게 대답할 수 있다(전자는 Yes, 후자는 No이다).

7


8

원리부터 배우는 관계형 데이터베이스 실전 입문

다른 한 가지는 집합의 요소가 중복돼서는 안 된다는 것이다. 집합에서 중요한 것은 어떤 요소가 포함돼 있는가 아니냐는 점이다. 예를 들어 어떤 집합 S에는 요소 e가 포함돼 있다 는 것을 다음과 같이 표현한다. e∈S

필요한 것은 e가 S에 포함돼 있는지 아닌지에 관한 정보뿐이다. 만약에 여러 개의 e가 S에 포함돼 있어도 이 식의 결과에는 영향을 주지 않는다. 원래 집합론에서는 같은 요소가 몇 개 포함돼 있는지는 의미를 갖지 않으며, 반대로 「몇 개 포함돼 있는가?」가 그다음의 연산 결과에 영향을 줘서는 안 된다. 더구나 집합의 요소는 더는 분해될 수 없다는 점도 중요하다. 요소는 요소 하나로서 의미가 있는 값이다. 요소 e가 집합 S에 포함돼 있는지 아닌지는 e 자체와 비교해서 처음 판정할 수 있다. e를 분해한 일부는 e와는 일치하지 않으므로 e ∈ S라는 판정에는 아무런 영향을 미치지 않는다. 이러한 특성이 다양한 집합의 조작에 있어 매우 중요하다. 집합이 무엇인지 확실하게 개념을 잡자. 관계형 모델은 집합론에 기인하는 데이터 모델이 다. 집합이 무엇인지 정확하게 이해하고 있는 것과 그렇지 않은 것에 따라서 관계형 모델에 관한 이해도도 달라질 것이다.

2 7 1 100 44

요소

11

그림 1.2 집합의 이미지

관계형 모델과 NULL 집합에서 알 수 없는 것을 포함하지 않는 것은 집합의 한 종류인 릴레이션에 NULL을 포함 할 수 없다는 의미다. 나중에 설명하겠지만, NULL은 값이 아니고 요소가 무엇인지 모르는, 즉 알 수 없는 값임을 나타내는 표식이다.


01 _ SQL과 관계형 모델

SQL에서 종종 NULL에 대해 옳고 그름이 화제가 되지만 관계형 모델을 올바르게 구현하 려면 NULL은 배제해야 한다. 관계형 모델에서 NULL이 필요하다고 생각하는 사람도 있지 만, 필자는 관계형 모델에서 NULL을 배제해야 한다는 의견이다. 논란의 여지는 있겠지만, 이 책에서는 독자 여러분도 이 관점에서 봤으면 한다.

NULL을 배제하면서 현실적인 문제에 어떻게 맞설 것인가가 이 책에서 다루는 하나의 주제 이기도 하다.

유한집합과 무한집합 집합에는 유한집합과 무한집합이라는 종류가 있다. 관계형 모델이 다루는 것은 유한집합뿐 이다. 컴퓨터로 표현할 수 있는 것은 어떤 종류이든지 유한이기 때문이다. 수치이든 문자열이든 구조화된 데이터이든 제한된 유형의 요소밖에 표현할 수 없다. 스토 리지의 용량이 크다면 엄청난 수의 요소를 표현할 수도 있겠지만, 그래도 요소의 수가 무한 대로 늘어나는 경우는 절대로 있을 수 없다. 마찬가지로 집합을 컴퓨터로 표현하더라도 요 소의 수를 무한으로 늘릴 수는 없을 것이다. 따라서 무한집합은 고려할 필요가 없다. 무한집합은 유한집합과 다른 성질을 가지고 있어서 무한에 대해서는 고려하지 않아도 될 만큼 관계형 모델은 심플한 모델로 되어 있다.

릴레이션의 연산 여기서부터가 본론이다. 지금까지 릴레이션이 무엇인지 이해했다고 생각하지만 단순하게 릴레이션으로 데이터를 표현하는 것만으로는 큰 도움이 되지 않는다. 데이터는 그에 대한 연산(또는 조작)과 세트로 사용될 때 의미가 있다. 객체지향에 관해 어느 정도 수준 이상으 로 알고 있는 사람이라면 데이터와 그에 대한 연산은 떼려야 뗄 수 없는 관계라는 것을 잘 알고 있을 것이다. 이것은 관계형 모델에서도 마찬가지다. 데이터를 릴레이션이라고 표현한다면 그에 대한 연 산은 쿼리(질의)다. 관계형 모델은 릴레이션 단위로 다양한 연산을 사용해 질의를 수행하 는 데이터 모델이다. 릴레이션을 사용한 연산을 수행하므로 관계형 모델이라고 부른다.

9


10

원리부터 배우는 관계형 데이터베이스 실전 입문

조금 전 릴레이션(의 본체)은 튜플의 집합이라고 설명했다. 릴레이션은 본질적으로는 집합 이며 그에 대한 연산도 집합론을 바탕으로 하고 있다. 그러나 릴레이션 내의 튜플이 모두 같은 구조, 즉 같은 이름, 같은 데이터형을 가지므로 일반적인 집합에는 없는 관계형 모델 특유의 연산이 많이 있다. 이어서 대표적인 릴레이션 연산을 소개하겠다.

제한(Restrict) 제한(Restrict)은 어떤 릴레이션들 중에 특정 조건에 맞는 튜플을 포함한 릴레이션을 반환 한다(그림 1.3). 제한을 실행한 결과는 원래 릴레이션의 부분집합이라고 할 수 있다. 조건 을 지정하는 방법은 특별히 제한을 두지 않는다. 따라서 제한을 실행한 결과가 공집합이 되 거나 원래의 릴레이션과 같은 결과가 나올 수도 있다.

프로젝션(Projection) 프로젝션(Projection)은 어떤 릴레이션에서 특정 속성만 포함하는 릴레이션을 반환한다 (그림 1.4). 속성이 적어지면 튜플의 중복이 발생할 수 있다. 예를 들어 그림 1.1의 릴레이 션에 대해 「지역」이라는 속성으로 프로젝션하면 「아시아」가 중복돼 버린다. 집합은 중복되 는 요소를 포함할 수 없으므로 중복이 발생한 경우 같은 튜플로 간주한다.


01 _ SQL과 관계형 모델

제한(Restrict)

그림 1.3 제한의 예

프로젝션(Projection)

그림 1.4 프로젝션의 예

11


12

원리부터 배우는 관계형 데이터베이스 실전 입문

확장(Extend) 확장(Extend)은 프로젝션과는 반대로 속성을 늘리는 동작이다. 대부분 새로운 속성값은 기존의 속성값을 이용해 계산한다. 그림 1.5는 인구와 면적이라는 두 가지 속성을 사용한 연산 결과로부터 인구밀도라는 새로운 속성을 확장하고 있다.

국가/문자열

면적/ 실수(km2)

인구/정수

확장(Extend)

국가/문자열

인구/정수

면적/ 실수(km2)

인구밀도/ 실수(사람/km2)

그림 1.5 확장의 예

속성명 변경(Rename) 속성명 변경(Rename)은 단순히 속성의 이름을 변경하는 동작이다. 그림 1.6에서는 기존 속성의 이름을 변경했지만, 실제로는 주로 확장한 속성에 대해 명칭을 부여할 때 많이 사용 한다.


01 _ SQL과 관계형 모델

국가/문자열

국가번호/정수

대륙/문자열

속성명 변경(Rename)

국가/문자열

국가번호/정수

지역/문자열

그림 1.6 속성명 변경의 예

합집합(Union) 합집합(Union)은 두 개의 릴레이션에 포함된 모든 튜플로 구성된 릴레이션(합집합)을 반 환한다(그림 1.7). 두 개의 릴레이션에 공통된 속성값이 포함됐다면 합집합은 중복 값이 제 거된 상태가 된다.

d

a

b

e

f

c

t

u

a

b

c

x

y

z

v

d

j

g

h

k

l

i

g

h

e

f

i

합집합(Union)

j

k

그림 1.7 합집합의 예

l

a

b

c

d

e

f

g

h

i

t

u

v

x

y

z

13


14

원리부터 배우는 관계형 데이터베이스 실전 입문

교집합(Intersect) 교집합(Intersect)은 두 개의 릴레이션에 모두 포함된(공통 부분) 릴레이션을 반환한다(그 림 1.8).

d

a

b

e

f

c

t

u

a

b

c

x

y

z

v

d

j

g

h

k

l

i

g

h

e

f

i

교집합/공통(Intersect)

a

b

c

d

e

f

g

h

i

그림 1.8 교집합의 예

차집합(Difference) 차집합(Difference)은 두 개의 릴레이션 중에 한쪽의 릴레이션에만 포함되어 있는 튜플로 구성된 릴레이션을 반환한다(그림 1.9). 차집합은 어느 쪽의 릴레이션을 기준으로 정하는 지에 따라서 결과가 달라지므로 주의하자10 .

10 교환 법칙이 성립하지 않는다.


01 _ SQL과 관계형 모델

d

a

b

e

f

c

t

u

a

b

c

x

y

z

v

d

j

g

h

k

l

i

g

h

e

f

i

차집합(Difference)

j

k

l

그림 1.9 차집합의 예

곱집합(Product) 곱집합(Product)은 두 개의 릴레이션에 있는 튜플을 각각 조합한 릴레이션을 반환한다(그 림 1.10). 이때 릴레이션의 제목은 두 개의 릴레이션의 제목이 가진 속성을 전부 포함한다.

a

b

x

c

d

z

y

곱집합(Product)

a

x

a

b

y

a

b

z

c

d

x

c

d

y

c

그림 1.10 곱집합의 예

b

d

z

15


16

원리부터 배우는 관계형 데이터베이스 실전 입문

결합(Join) 결합(Join)은 공통된 속성을 가진 두 개의 릴레이션에서 공통된 속성값이 같은 튜플끼리 조합한 릴레이션을 반환한다(그림 1.11).

a

x

w

1

b

y

x

2

c

z

x

3

결합(Join)

a

x

2

a

x

3

그림 1.11 결합의 예

결과적으로 반환되는 튜플은 두 개의 릴레이션에서 공통된 속성에 관해 같은 값이 존재하 는 것뿐이다. 즉 일치하는 값이 존재하지 않는 튜플은 결과에서 제외된다. 이와 같은 형태 의 결합을 SQL에서는 내부조인(INNER JOIN)이라고 한다. 사실은 관계형 모델에 존재하 는 것은 내부조인뿐이다. 외부조인은 결과에 NULL이 포함될 가능성이 있으므로 릴레이션 의 연산으로는 부적절하다. 덧붙여서 말하면 교집합과 곱집합은 결합의 특수한 예다. 교집합은 두 개의 릴레이션에 포 함되는 속성이 전부 공통인 경우이고 반대로 곱집합은 공통의 속성이 존재하지 않는 경우 다. 사소한 정보이지만 이런 것들을 알아두면 릴레이션의 연산이 조금은 친근하게 느껴질 것이다.

◆◆◆ 여기까지가 대표적인 릴레이션의 연산이다. 이러한 연산을 사용해 릴레이션으로부터 필요 한 정보를 추출할 수 있다. 이것이 쿼리의 본질이다. 이 원리를 응용해 만들어진 것이 RDB 이다. RDB가 성능을 최대한 발휘하려면 이런 동작을 기반으로 SQL을 작성해야 한다.


01 _ SQL과 관계형 모델

Column 요소에 NULL이 포함돼 있으면 만약 릴레이션에 NULL이 포함돼 있으면 관계형 모델은 성립하지 않는다. NULL은 값을 모르는 상태를 나타내 는 표식이다. 따라서 NULL이 포함돼 있으면 릴레이션 연산 결과가 항상 같아지지 않는다. 그림 1.1의 릴레이션에서 모든 속성이 NULL인 튜플 t가 있다고 하면 이 릴레이션에 대해 「지역 = 아시아」라는 조건으로 제한을 실행하면 이 튜플 t를 결과에 포함해야 할까? SQL 구조로 본다면 포함하지 않는 것이 맞지만 여기서는 NULL의 의미를 좀 더 깊게 살펴보자. NULL은 구체적인 값이 불분명하므로 아시아일 수도 있고, 아시아가 아닐 수도 있다. 결과에 포함되지 않는다 는 것은 「아시아가 아니다」라고 단언한다는 것을 의미하지만, 값을 모른다면 아시아일 가능성도 배제할 수 없 다. 따라서 제한의 결과에 포함해야 할지를 판단할 수 없다. 이러한 상황이 곤란한 점이다. 프로젝션은 어떨까? 지역이라는 속성으로 프로젝션했을 때 과연 튜플 t의 지역은 다른 튜플들과 중복될 것인 가? 중복될 수도 있고 아닐 수도 있다. 조금 전에 설명한 제한과 마찬가지로 어느 쪽이라고 단언할 수 없다. 이처럼 NULL이라는 것은 NULL로 된 속성값을 모르는 것뿐 아니라 릴레이션 연산 결과가 어떻게 될지 모른다. 제한과 프로젝션으로 한 개의 릴레이션에 대한 동작을 예로 들어 NULL의 문제를 설명했지만, NULL이 문제가 되는 것은 여러 개의 릴레이션을 대상으로 한 동작에서도 마찬가지다. 그림 1.a를 참고하자.

R1

R2

a

x

w

1

b

y

x

2

c

NULL

NULL

3

그림 1.a NULL이 포함된 릴레이션

두 개의 릴레이션에 각각 NULL이 포함돼 있다. R1과 R2를 결합(Join)하면 과연 NULL을 포함한 튜플은 어떤 튜플과 결합해야 할까? 아니면 결합하지 않아야 할까? 혹은 NULL끼리 결합할 수 있을까? 표시는 NULL이어도 실제로 NULL은 어떤 값인지 모른다. 만약 R1의 NULL이 w라면 이 튜플은 R2에서 일치하 는 튜플과 결합해야 한다. 마찬가지로 R2의 NULL이 y라면 이 튜플은 R1에서 일치하는 튜플과 결합해야 한다.

17


18

원리부터 배우는 관계형 데이터베이스 실전 입문

어쩌면 R1과 R2의 NULL은 w도 y도 아니지만 같은 값(예를 들어 양쪽 모두 z)일지도 모른다. 그렇다면 NULL 을 포함하는 튜플들은 결합해야 한다. 결합한 결과는 NULL의 실제값이 무엇인지에 따라서 1~3개의 튜플이 포함될 가능성이 있다. 하지만 정답이 무 엇인지는 아무도 모를 것이다. 왜냐하면, NULL의 실제 값이 무엇인지 모르기 때문이다. 만약 편의상 “NULL끼리는 같다고 가정한다”거나 “NULL이 다른 NULL에도 포함돼 어떤 값이어도 같지 않다 고 가정한다”와 같이 규칙을 적용하면 어떨까? 어느 쪽이든 논리적으로는 정답이 아니다. NULL 값은 알 수 없으므로 다른 튜플과 같을 수도 있고 그렇지 않을 수도 있다. 이를 모두 같거나 같지 않다고 간주하는 것은 단순히 결과를 왜곡하는 것으로 끝나지 않는다. 따라 서 NULL이 포함된 릴레이션의 연산 결과는 알 수 없을 뿐 아니라 논리적으로 정답이 아니다. 이처럼 NULL은 관계형 모델의 근본을 뒤집는 불안정한 요소다.

클로저(closure)라는 성질 관계형 모델에서 중요한 것은 릴레이션을 사용한 연산 결과가 릴레이션이 되는 것이다. 예를 들어 절차형 언어에서 정수값의 연산에 관해 생각해 보자. 어떤 정수값 두 개를 사용 한 연산이 다시 정수값이 되고 그 결과를 사용해 다른 정수와 연산을 수행할 수 있다. 이처럼 연산의 입력과 출력이 같은 데이터 구조를 가진 성질을 클로저(폐쇄)라고 한다11 . 입력과 출력이 같은 데이터 구조라는 성질은 매우 중요하다. 연산 결과를 새롭게 입력해 꼬 리에 꼬리를 무는 것처럼 연산을 기술하여 복잡한 연산을 표현할 수 있기 때문이다. 연산의 단위가 릴레이션일 때도 마찬가지다. 연산 결과가 릴레이션이라면 그 결과를 다른 릴레이션과 조합해 연산할 수 있다는 의미다. 예를 들어 두 개의 릴레이션의 합집합에 다른 릴레이션을 결합하고 그 결과에 제한을 적용 하거나, 프로젝션을 적용하거나, 다른 릴레이션과의 합집합을 연산하는 것과 같은 형태다. 이처럼 릴레이션의 연산만을 이용해 복잡한 연산을 표현할 수 있다는 점이 관계형 모델의 진면목이라 할 수 있다.

11 여기에서 클로저는 람다식이나 무명함수를 말하는 것이 아니다.


01 _ SQL과 관계형 모델

관계형 모델의 데이터 형식 이번 절에서는 관계형 모델을 이해하는 데 있어 중요한 개념인 데이터 형식에 관해 설명한 다. 데이터 형식이란 각 속성이 어떤 값을 가질 것인지를 말한다. 이 점은 관계형 모델을 이 해하는 데 있어 매우 중요한 개념이다. 테이블을 설계할 때에 데이터 형식(또는 유형)을 고려하지 않는 경우는 없다고 생각한다.

SQL의 데이터 형식으로는 INT나 CHAR, VARCHAR와 같은 것이 있다. 관계형 모델에 대입할 때 다양한 데이터 형식을 어떻게 구분 지어야 할까? 관계형 모델 자신은 「어떤 데이터 형식을 사용해야 할까?」라고 결정하지 않는다. 관계형 모 델은 문자 그대로 「모델」이므로 어떻게 사용할 수 있는지가 정해져 있을 뿐 “어떻게 사용해 야 한다”는 모델을 사용하는 응용프로그램이 정해야 한다. 예를 들어 C언어 프로그램에서 변수의 형식을 int로 해야 할지, float로 해야 할지를 선택해야 하는 것처럼 모든 것은 응용 프로그램에 달려있다.

데이터 형식과 변수 관계형 모델의 데이터 형식을 설명하기 전에 좀 더 일반적인 데이터 형식에 관해 생각해 보자. 데이터 형식이란 무엇일까? 데이터 형식을 이해하려면 먼저 변수와 값에 대해 이해해야 한다. 변수란 값을 대입할 수 있는 그릇이다. 변수의 내용은 프로그램이 실행되면서 끊임없이 변 한다. 또한, 값은 여러 종류가 있지만 각각의 값이 갖는 의미는 일반적이다. 어떤 값이 다른 의미나 양을 가지지 않는다. 예를 들어 x라는 변수의 값이 1이라는 정수이며 x에 다른 값(예를 들어 2)을 대입해 내용 이 변경될 수 있다. 하지만 1이라는 값의 의미와 양에는 변화가 없다.

19


20

원리부터 배우는 관계형 데이터베이스 실전 입문

도메인이란 컴퓨터 프로그램에서 어떤 변수에 대입할 수 있는 값은 어떤 것일까? 변수에 대입할 수 있 는 값은 무한정한 값이 아니며, 사용할 수 있는 범위가 한정돼 있다. 집합의 항목에서 설명 한 것처럼 컴퓨터가 표현할 수 있는 데이터는 변경할 수 있는 한계가 있다. 즉, 데이터 형식은 그 변수에 대입할 수 있는 값의 유한집합이다. 관계형 모델에서 데이터 형식은 도메인이라고 한다. 값은 그 집합의 요소 하나하나이고 변 수는 어떤 시점에 그 집합에서 요소를 한 개 선택한 것으로 해석한다. 집합의 요소(값)에는 변화가 없지만 어떤 요소를 선택할 것인가(변수)는 시시각각 변할 것이다. 그 집합 전체를 도메인이라고 한다. 이제 릴레이션을 생각해보자. 속성의 「데이터 형식」, 즉 도메인이 유한집합이라는 것은 튜 플이 취득할 수 있는 값을 그 유한집합의 곱집합으로 나타낼 수 있다는 말이다. 예를 들어 10가지의 값을 가질 수 있는 속성이 두 개인 튜플은 100가지의 값을 가질 수 있 다. 튜플은 제목에 정의된 속성의 곱집합 중 한 개의 요소다. 릴레이션은 속성의 도메인의 곱집합에서 특정 튜플만 선택해 구성한 집합이다. 이처럼 관계형 모델은 릴레이션을 구성하는 제목, 본체, 튜플뿐만 아니라 속성의 데이터 형 식조차도 집합으로 되어 있다. 이러한 것을 볼 때 집합의 본질을 이해하는 것이 얼마나 중 요한지 알 수 있다. 또한, 집합의 성격에서 벗어난 사용법이 데이터 모델에서 얼마나 좋지 않은지 이해가 되지 않는가?

1.3 SQL에서 릴레이션 조작 릴레이션과 그 연산의 변형을 훑어보면서 몇 가지의 DML ( Data Manipulation

Language, 데이터 조작 언어)을 예로 들어 SQL이 릴레이션과 어떻게 대응되는지 설명하 겠다.

SQL과 관계형 모델은 차이가 크지만 대응하는 부분도 많다. 구체적인 예를 보면 릴레이션 의 조작이 어떤 것인지 이해하기 쉬울 것이다. 관계형 모델에서 벗어나서 사용하지 않는다


01 _ SQL과 관계형 모델

면 SQL과 관계형 모델의 대응에 관해 쉽게 이해할 수 있을 것이다.

SELECT의 기본형 평소 무심코 사용하는 SELECT 문이 관계형 모델에서 어떤 의미의 연산을 할까?

SELECT는 RDB의 핵심이다. ‘어떻게 하면 SELECT를 잘 쓸 수 있을까’가 RDB를 능숙하 게 다루기 위한 핵심이라고 해도 과언이 아니다. 그러므로 SELECT가 논리적으로 어떤 의 미가 있는지 알고 있어야 한다.

SELECT는 SQL에서 데이터를 조회하는 데 사용하는 유일한 명령이다. 「질의」 기능은 전부 SELECT에 들어있다. SELECT는 매우 강력한 명령으로 유연성이 높고 다양하게 응용할 수 있다. 그만큼 미숙한 프로그래머가 작성하면 복잡하고 난해해지기 쉽다. 여기서는 SELECT 의 기본형에 관해 설명한다.

UNION이나 서브쿼리가 없는 간단한 SELECT는 리스트 1.1과 같은 구문으로 되어 있다. 리스트 1.1 SELECT의 기본형

SELECT 칼럼의 목록 FROM 테이블의 목록 WHERE 검색 조건

그리고 여기서 중요한 점은 리스트 1.1의 세 항목 모두가 각각 릴레이션의 대수 연산에 해 당한다. 칼럼의 목록은 프로젝션(Projection), 테이블의 목록은 곱집합(Product), 검색조 건은 제한(Restrict)이다. 이처럼 간단한 SELECT는 세 개의 릴레이션 연산을 동시에 수행 하는 작업이다. 필자가 이 사실을 알았을 때 굉장히 놀랐다. SELECT의 구조를 이해하는 단 하나의 사실만으로 많은 부분을 알게 됐다.

SELECT를 이해하는 데 있어 또 하나의 매우 중요한 사실이 있다. 각 연산이 평가되는 순 서다. SELECT에서는 세 가지의 릴레이션 연산이 다음과 같은 순서로 평가된다. ➊ 테이블의 목록 (곱집합)

21


22

원리부터 배우는 관계형 데이터베이스 실전 입문

➋ 검색 조건 (제한) ➌ 칼럼의 목록 (프로젝션)

평가하는 순서를 이해하고 있으면 실제로 SELECT 문을 작성할 때 유용하다. 구체적인 예 로 리스트 1.2에 있는 SELECT의 의미를 생각해보자. 리스트 1.2 SELECT 문의 예

SELECT t1.c1, t1.c2, t2.c3 FROM t1 INNER JOIN t2 WHERE t1.c4 = t2.c5 AND t2.c6 < 100;

이 SELECT 문이 갖는 의미는 t1과 t2의 곱집합에 대해서 t1.c4 = t2.c5 AND t2.c6 < 100 이라는 조건의 제한을 적용하고 그 결과에서 t1.c1, t1.c2, t2.c3의 칼럼만 출력되게 프로 젝션을 하는 것이다. 한 가지 주의할 점은 SELECT 문에서 이런 항목들이 평가되는 순서와 실제로 RDB에 의해 어떤 순서로 실행되는지는 관계가 없다. 아마 대부분의 RDB에서는 옵티마이저가 최적화 를 실시해 처리를 생략하거나 실행 순서를 바꾸게 된다. 예를 들어 테이블의 행을 가져올 때 가능한 한 필요한 칼럼만 가져올 것이고, 원래 테이블 에서 가져올 행은 WHERE 절의 조건에 따라서 최소화하므로 중간에서 곱집합을 생성하는 처리는 없다. 여기서 말하는 SELECT의 평가 순서는 어디까지나 논리적인 의미라는 걸 기억하자. RDB 가 수행하는 최적화는 구현된 기능이다. SELECT가 보여주려는 내용과 같은 결과가 생성 된다면 실행되는 부분은 어떻게 구현돼도 상관없다. 지금까지 내용을 정리하면 SELECT는 논리적인 곱집합, 제한, 프로젝션의 세 가지의 릴레 이션 연산을 동시에 수행하는 작업이다. SELECT에 관해서는 8장에서 자세하게 설명한다. 우선 SELECT의 기본형이 무엇을 의미하는지 이해하자.


관계형 데이터베이스 실전 입문 : 원리부터 배우는  

오쿠노 미키야 지음 | 성창규 옮김 | 데이터베이스 & 빅데이터 시리즈_014 | ISBN: 9791158390372 | 28,000원 | 2016년 07월 22일 발행 | 336쪽 | SQL, 관계형 데이터베이스, 관계형 모델, 데이터베이스, 집합...

Read more
Read more
Similar to
Popular now
Just for you