중요

번역은 여러분이 참여할 수 있는 커뮤니티 활동입니다. 이 페이지는 현재 82.95% 에서 번역되고 있습니다.

15.1. Lesson: Introduction to Databases

PostgreSQL을 사용해보기 전에, 일반적인 데이터베이스 이론으로 기초를 다지도록 합시다. 어떤 예제 코드도 입력할 필요 없습니다. 모든 코드는 오직 설명을 목적으로 합니다.

이 강의의 목표: 핵심적인 데이터베이스 개념들을 이해하기.

15.1.1. 데이터베이스란 무엇일까요?

데이터베이스는 하나 또는 그 이상의 용도로 쓰이는, 일반적으로 디지털 형태인, 데이터의 조직화된 집합으로 이루어진다. - 위키백과

DBMS(데이터베이스 관리 시스템)는 저장소, 접속, 보안, 백업 및 기타 기능을 제공하는, 데이터베이스를 조작하는 소프트웨어로 이루어진다. - 위키백과

15.1.2.

관계형 데이터베이스 및 플랫 파일 데이터베이스에서, 테이블이란 (명칭으로 식별되는) 수직 열과 수평 행의 모델을 사용해 조직된 데이터 요소(값)들의 집합이다. 테이블의 열은 지정된 개수이지만, 행은 무한대로 확장될 수 있다. 각 행은 후보 키라고 식별되는 특정 열 서브셋에 나타나는 값으로 식별된다. - 위키백과

 id | name  | age
----+-------+-----
  1 | Tim   |  20
  2 | Horst |  88
(2 rows)

SQL 데이터베이스에서는 테이블을 관계 라고도 합니다.

15.1.3. 열/필드

열이란 테이블의 각 행의 하나씩을 차지하는, 특정 단순형 데이터 값들의 집합이다. 열은 어떤 행들로 이루어지느냐에 따르는 구조를 제공한다. 필드라는 용어는 종종 열과 바꿔 쓰이기도 하지만, 많은 이들은 필드(또는 필드 값)을 한 행과 한 열의 교차 지점에 있는 단일 값을 특별히 지칭하는 용어라고 간주한다. - 위키백과

열 :

| name  |
+-------+
| Tim   |
| Horst |

필드 :

| Horst |

15.1.4. 레코드

레코드란 테이블의 행에 저장된 정보를 말합니다. 각 레코드는 테이블 안 각 열에 대한 필드를 차지하게 됩니다.

2 | Horst |  88  <-- one record

15.1.5. 데이터형

데이터형이란 열에 저장될 수 있는 정보의 유형을 제한한다. - Tim & Horst

여러 유형의 데이터형이 있습니다. 가장 흔히 쓰이는 데이터형에 대해 알아봅시다.

  • 문자열(string) - 자유 서식 텍스트 데이터를 저장

  • 정수(integer) - 범자연수(whole number)를 저장

  • 실수(real) - 십진수(decimal number)를 저장

  • 날짜(date) - 아무도 잊지 않도록 Horst의 생일을 저장

  • 불(boolean) - 단순한 참/거짓 값을 저장

데이터베이스가 필드에 아무것도 저장하지 않도록 할 수도 있습니다. 필드에 아무것도 없을 경우, 필드의 내용을 ‘널(null)’ 값 이라고 합니다:

insert into person (age) values (40);

select * from person;

결과 :

id | name  | age
---+-------+-----
 1 | Tim   |  20
 2 | Horst |  88
 4 |       |  40  <-- null for name
(3 rows)

더 많은 데이터형을 사용할 수 있습니다. PostgreSQL 매뉴얼을 살펴보세요!

15.1.6. 주소 데이터베이스 모델링

간단한 예제를 통해 데이터베이스가 어떻게 구성되는지 알아봅시다. 주소 데이터베이스를 생성하겠습니다.

Try Yourself: ★☆☆

단순한 주소를 적어보고, 어떤 요소로 이루어져 있는지 그리고 데이터베이스에 어떤 요소를 저장해야 할지 생각해보십시오.

주소의 구조

주소를 표현하는 요소가 곧 열입니다. 각 열에 저장되는 데이터의 유형이 곧 데이터형입니다. 다음 단계에서 이 개념적인 주소 테이블을 분석해서 어떻게 향상시킬 수 있는지 알아보겠습니다!

15.1.7. 데이터베이스 이론

데이터베이스를 생성하는 과정은 실재 세계의 모형을 생성하는 것입니다. 실재 세계의 개념을 취해서 데이터베이스에 엔티티로서 표현하는 것입니다.

15.1.8. 정규화

데이터베이스의 주요 아이디어 가운데 하나는 데이터의 복제/중복을 피하자는 것입니다. 데이터베이스에서 중복을 제거하는 과정을 정규화라고 합니다.

정규화란 데이터베이스의 구조가 범용 쿼리 및, 데이터 무결성을 잃을 수 있는 바람직하지 않은 특정 특성들 - 삽입, 업데이트, 삭제 이상 - 을 피하는 데 적합한지 확인하는 체계적인 방법이다. - 위키백과

정규화 ‘서식’에는 서로 다른 유형들이 있습니다.

간단한 예를 살펴보겠습니다:

Table "public.people"

Column    |          Type          |                Modifiers
----------+------------------------+------------------------------------
 id       | integer                | not null default
          |                        | nextval('people_id_seq'::regclass)
          |                        |
 name     | character varying(50)  |
 address  | character varying(200) | not null
 phone_no | character varying      |
Indexes:
 "people_pkey" PRIMARY KEY, btree (id)
select * from people;

id |     name      |           address           |  phone_no
---+---------------+-----------------------------+-------------
 1 | Tim Sutton    | 3 Buirski Plein, Swellendam | 071 123 123
 2 | Horst Duester | 4 Avenue du Roix, Geneva    | 072 121 122
(2 rows)

동일한 도로명 또는 도시명을 가진 친구들이 많다고 상상해보십시오. 이 데이터가 복제될 때마다 용량을 소비하게 됩니다. 더구나 도시명이 변경될 경우, 데이터베이스를 업데이트하는 데 많은 작업을 해야 합니다.

15.1.9. Try Yourself: ★☆☆

복제를 줄이고 데이터 구조를 정규화하기 위해 앞의 이론적인 ‘people’ 테이블을 재설계해보십시오.

데이터베이스 정규화에 대해 이곳 에서 더 읽어볼 수 있습니다.

15.1.10. 인덱스

데이터베이스 인덱스란 데이터베이스 테이블에서 데이터 검색 작업의 속도를 향상시키는 데이터 구조이다. - 위키백과

교과서를 읽다가 어떤 개념에 대한 설명을 찾는다고 상상해보십시오 - 그런데 교과서에 색인이 없군요! 여러분은 필요한 정보를 찾을 때까지 표지부터 책 전체를 다시 훑어야 할 겁니다. 책의 끝부분에 있는 색인은 관련 정보가 있는 페이지를 빨리 찾을 수 있게 해줍니다:

create index person_name_idx on people (name);

이제 성명 검색이 빨라질 겁니다:

Table "public.people"

Column   |          Type          |               Modifiers
----------+------------------------+-------------------------------------
 id       | integer                | not null default
          |                        | nextval('people_id_seq'::regclass)
          |                        |
 name     | character varying(50)  |
 address  | character varying(200) | not null
 phone_no | character varying      |
Indexes:
 "people_pkey" PRIMARY KEY, btree (id)
 "person_name_idx" btree (name)

15.1.11. 시퀀스

시퀀스란 유일 숫자 생성기입니다. 보통 테이블의 어떤 열을 위한 유일한 식별자를 생성하는 데 쓰입니다.

이 예제에서는 id가 시퀀스입니다. 테이블에 레코드가 추가될 때마다 숫자가 증가합니다:

id |     name     |           address           |  phone_no
---+--------------+-----------------------------+-------------
 1 | Tim Sutton   | 3 Buirski Plein, Swellendam | 071 123 123
 2 | Horst Duster | 4 Avenue du Roix, Geneva    | 072 121 122

15.1.12. 엔티티 관계 도표

정규화된 데이터베이스는 일반적으로 많은 관계(테이블)을 가지게 됩니다. 이 관계들 사이의 논리적 의존성을 설계하는 데 엔티티-관계 도표(ER Diagram)를 사용합니다. 이전 단계의 아직 정규화되지 않은 ‘people’ 테이블을 생각해보십시오:

select * from people;

 id |     name     |           address           |  phone_no
----+--------------+-----------------------------+-------------
 1  | Tim Sutton   | 3 Buirski Plein, Swellendam | 071 123 123
 2  | Horst Duster | 4 Avenue du Roix, Geneva    | 072 121 122
(2 rows)

같은 거리에 사는 개인들에 대해 도로명을 반복할 필요가 없도록 이 테이블을 손쉽게 두 테이블로 나눌 수 있습니다:

select * from streets;

 id |     name
----+--------------
 1  | Plein Street
(1 row)

이렇게 하면,

select * from people;

 id |     name     | house_no | street_id |  phone_no
----+--------------+----------+-----------+-------------
  1 | Horst Duster |        4 |         1 | 072 121 122
(1 row)

이 두 테이블을 streets.idpeople.streets_id 라는 ‘키’를 이용해서 연결할 수 있습니다.

이 두 테이블에 대해 ER 도표를 그린다면 다음과 같이 보일 것입니다.

../../../_images/er-people-streets.png

ER 도표를 통해 ‘일대다’ 관계를 표현할 수 있습니다. 이 예제에서 화살표는 한 도로에 많은 사람이 살 수 있다는 사실을 보여줍니다.

Try Yourself: ★★☆

이 ‘people’ 모델에는 아직 몇몇 정규화 문제가 남아 있습니다. 사용자 스스로 더 정규화를 진행시킬 수 있을지 생각해보고, ER 도표로 사용자의 생각을 표현해보십시오.

15.1.13. 제약 조건, 기본 키, 외래 키

데이터베이스 제약 조건은 관계 안에 있는 데이터가 어떻게 데이터가 저장되어야 하는지에 대한 모델러의 시각과 일치하는지 확인하는 데 쓰입니다. 예를 들어 우편번호에 대한 제약 조건으로 10009999 사이의 숫자만 저장되도록 할 수 있습니다.

기본 키는 레코드를 유일하게 만들어주는 하나 이상의 필드 값입니다. 기본 키를 보통 id라고 하며, 시퀀스인 경우가 대부분입니다.

외래 키는 유일한 레코드를 (해당 테이블의 기본 키를 써서) 다른 테이블에 참조시키는 데 쓰입니다.

ER 도표를 그릴 때, 테이블 사이의 연결은 보통 기본 키와 연결되는 외래 키에 기반하고 있습니다.

이 ‘people’ 예제를 보면, 테이블 정의에서 street 열이 streets 테이블의 기본 키를 참조하는 외래 키라는 사실을 보여주고 있습니다:

Table "public.people"

 Column    |         Type          |  Modifiers
-----------+-----------------------+--------------------------------------
 id        | integer               | not null default
           |                       | nextval('people_id_seq'::regclass)
 name      | character varying(50) |
 house_no  | integer               | not null
 street_id | integer               | not null
 phone_no  | character varying     |
Indexes:
"people_pkey" PRIMARY KEY, btree (id)
Foreign-key constraints:
"people_street_id_fkey" FOREIGN KEY (street_id) REFERENCES streets(id)

15.1.14. 트랜잭션

데이터베이스에서 데이터를 추가, 변경, 삭제할 때 뭔가 문제가 발생해도 데이터베이스는 언제나 양호한 상태로 남아 있어야 합니다. 대부분의 데이터베이스는 트랜잭션 지원이라는 기능을 제공합니다. 트랜잭션은 데이터베이스에 대한 사용자의 수정 작업이 계획대로 되지 않았을 경우 되돌아갈 수 있는 복원 지점을 생성할 수 있게 해줍니다.

사용자가 은행 계좌 시스템을 가지고 있다고 생각해보십시오. 어떤 계좌에서 다른 계좌로 자금을 전송해야 합니다. 이 일련의 단계를 다음과 같이 가정해볼 수 있습니다.

  • 조에게서 R20을 출금

  • 앤에게 R20을 입금

이 과정에서 무언가 (정전 같은) 문제가 생길 경우, 트랜잭션이 이전으로 복원됩니다.

15.1.15. In Conclusion

데이터베이스를 이용하면 간단한 코드 구조를 써서 데이터를 구조화된 방법으로 관리할 수 있습니다.

15.1.16. What’s Next?

이제 데이터베이스가 이론적으로 어떻게 작동하는지 알아봤으니, 지금 배운 이론을 시행할 수 있는 새 데이터베이스를 생성해봅시다.