SQL, 관계형 데이터베이스 설계
SQL 소개
데이터베이스의 필요성
앞서 데이터를 저장하는 방법으로 파일에 데이터를 저장하거나, 인메모리 형태로 데이터를 임시 저장하는 방법을 이용했습니다. 이 방법으로도 데이터를 저장할 수 있는데, 굳이 데이터베이스를 사용할 필요가 있을까요? 데이터베이스를 사용하지 않고, 엑셀 시트나 CSV 파일 등에 데이터를 저장해 사용하면 되지 않을까요? 이번 챕터에서 그 의문을 해결할 수 있습니다.
1. In-Memory
먼저 JavaScript에서 데이터를 다룰 때에는 프로그램이 실행될 때에만 존재하는 데이터가 있습니다.
JavaScript에서 변수를 만들어 저장한 경우, 프로그램이 종료될 때 해당 프로그램이 사용하던 데이터도 사라집니다. 이 말은 변수 등에 저장한 데이터가 프로그램의 실행에 의존한다는 말입니다. 예기치 못한 상황으로부터 데이터를 보호할 수 없고, 프로그램이 종료된 상태라면 데이터를 원하는 시간에 받아올 수 없으며, 데이터의 수명이 프로그램의 수명에 의존하게 됩니다.
2. File I/O
파일을 읽는 방식으로 작동하는 형태를 말합니다. 엑셀 시트나 CSV 같은 파일의 형태는 In-Memory에 비해 데이터를 저장하는 방식으로 적절해 보입니다. 그러나 한계가 분명히 존재합니다.
- 데이터가 필요할 때마다 전체 파일을 매번 읽어야 합니다. 파일의 크기가 커질수록 이 작업은 버겁고, 비효율적이어서 File I/O 방식의 큰 단점입니다.
- 파일이 손상되거나 여러 개의 파일들을 동시에 다뤄야 하거나 하는 등 복잡하고 데이터량이 많아질수록 데이터를 불러들이는 작업이 점점 힘들어집니다.
반면에 관계형 데이터베이스에서는 하나의 CSV 파일이나 엑셀 시트를 한 개의 테이블로 저장할 수 있습니다. 한 번에 여러 개의 테이블을 가질 수 있기 때문에 SQL 을 활용해 데이터를 불러오기 수월합니다. 또한, 엑셀 시트와 CSV 파일 등처럼 특정 형태의 파일은 대용량의 데이터를 저장하기 위한 목적이 아닙니다.
SQL 소개
- 하나의 언어인 Structured Query Language (SQL)은 데이터베이스 언어로, 주로 관계형 데이터베이스에서 사용합니다. 예를 들어 MySQL, Oracle, SQLite, PostgreSQL 등 다양한 데이터베이스에서 SQL 구문을 사용할 수 있습니다.
- SQL이란 데이터베이스 용 프로그래밍 언어입니다. 데이터베이스에 쿼리를 보내 원하는 데이터를 가져오거나 삽입할 수 있습니다. 그리고 이름에서 유추할 수 있듯이, SQL은 (relation 이라고도 불리는) 데이터가 구조화된(structured) 테이블을 사용하는 데이터베이스에서 활용할 수 있습니다.
- SQL을 사용할 수 있는 데이터베이스와 달리, 데이터의 구조가 고정되어 있지 않은 데이터베이스를 NoSQL이라고 합니다. 관계형 데이터베이스와는 달리, 테이블을 사용하지 않고 데이터를 다른 형태로 저장합니다. NoSQL의 대표적인 예시는 MongoDB 와 같은 문서 지향 데이터베이스입니다.
- 이처럼 데이터베이스 세계에서 SQL은 데이터베이스 종류를 SQL이라는 언어 단위로 분류할 정도로 중요한 자리를 차지하고 있습니다. 그리고 SQL을 사용하기 위해서는 데이터가 구조가 고정되어 있어야 합니다.
SQL은 구조화된 쿼리 언어입니다.
쿼리란 ?
쿼리(query)란 무엇일까요? 쿼리는 ‘질의문’ 이라는 뜻을 가지고 있습니다. 예를 들면 검색할 때 입력하는 검색어가 일종의 쿼리입니다. 검색을 할 때, 기존에 존재하는 데이터를 검색어로 필터링합니다. 따라서, 쿼리는 저장되어 있는 데이터를 필터하기 위한 질의문으로도 볼 수 있습니다.
스키마(schema) 란 ?
- 데이터베이스에서 데이터가 구성되는 방식과 서로 다른 엔티티 간의 관계에 대한 설명
- 즉, “데이터베이스의 청사진”
엔티티(Entity)는 고유한 정보의 단위입니다. 엔티티는 데이터베이스에서 테이블로 표시할 수 있습니다.
각 엔티티에는 해당 엔티티의 특성을 설명하는 필드(Field)가 있습니다. 행렬이라면 열(column)에 해당되겠죠.
테이블에 저장된 모든 항목에는 해당 필드가 포함됩니다.
레코드(record)는 테이블에 저장된 항목입니다. 행렬에서의 행(row)이라고 볼 수도 있습니다.
데이터베이스 설계
관계형 데이터베이스
구조화된 데이터는 하나의 테이블로 표현할 수 있습니다. 사전에 정의된 테이블을 relation 이라고도 부르기 때문에, 테이블을 사용하는 데이터베이스를 관계형 데이터베이스(Relational database)라고 합니다.
다음은 관계형 데이터베이스를 학습하면서, 반드시 알고 있어야 하는 키워드입니다.
- 데이터(data): 각 항목에 저장되는 값입니다.
- 테이블(table; 또는 relation) : 사전에 정의된 열의 데이터 타입대로 작성된 데이터가 행으로 축적됩니다.
- 칼럼(column; 또는 field) : 테이블의 한 열을 가리킵니다.
- 레코드(record; 또는 tuple) : 테이블의 한 행에 저장된 데이터입니다.
- 키(key) : 테이블의 각 레코드를 구분할 수 있는 값입니다. 각 레코드마다 고유한 값을 가집니다. 기본키(primary key)와 외래키(foreign key) 등이 있습니다.
관계 종류
테이블과 테이블 사이의 관계는 다음과 같습니다.
- 1:1 관계
- 1:N 관계
- N:N 관계
테이블 스스로 관계를 가질 수도 있습니다.
- self referencing 관계
1:1 관계
하나의 레코드가 다른 테이블의 레코드 한 개와 연결된 경우입니다. 다음과 같이 User 테이블과 Phonebook 테이블이 있다고 가정하겠습니다.
[그림] User table과 Phonebook table의 1:1 관계
User 테이블은 user_id, name, phone_id를 가지고 있습니다. 이 중 phone_id는 외래키(foreign key)로써, Phonebook 테이블의 phone_id와 연결되어 있습니다. Phonebook 테이블은 phone_id와 phone_number를 가지고 있습니다.
각 전화번호가 단 한 명의 유저와 연결되어 있고, 그 반대도 동일하다면, User 테이블과 Phonebook 테이블은 1:1 관계(One-to-one relationship)입니다.
그러나 1:1 관계는 자주 사용하지 않습니다. 1:1로 나타낼 수 있는 관계라면 User 테이블에 phone_id를 대신해 phone_number를 직접 저장하는 게 나을 수 있습니다.
1:N 관계
하나의 레코드가 서로 다른 여러 개의 레코드와 연결된 경우입니다. User 테이블과 Phonebook 테이블의 관계를 다음과 같이 가정하겠습니다.
N:N 관계
여러 개의 레코드가 다른 테이블의 여러 개의 레코드와 관계가 있는 경우입니다. N:N(다대다) 관계를 위해 스키마를 디자인할 때에는, Join 테이블을 만들어 관리합니다. 1:N(일대다) 관계와 비슷하지만, 양방향에서 다수의 레코드를 가질 수 있습니다.
다음과 같이 여행 상품을 관리하는 테이블이 있다고 가정하겠습니다. 여러 개의 여행 상품이 있고, 여러 명의 고객이 있습니다. 고객 한 명은 여러 개의 여행 상품을 구매할 수 있고, 여행 상품 하나는 여러 명의 고객이 구매할 수 있습니다.
이렇게 Customer 테이블과 Package table이 따로 존재한다면, N:N(다대다) 관계를 어떻게 표현할 수 있을까요? 다대다 관계는 두 개의 일대다 관계와 그 모양이 같습니다. 두 개의 테이블과 1:N(일대다) 관계를 형성하는 새로운 테이블로 N:N(다대다) 관계를 나타낼 수 있습니다.
이렇게 다대다 관계를 위한 테이블을 조인 테이블이라고 합니다. N:N(다대다) 관계를 그림으로 나타내면 다음과 같습니다.