Database
- 데이터를 저장 및 보존하는 시스템
- Applicaion에서는 데이터가 메모리상에서 존재하는데 메모리에 존재하는 데이터는 보존이 되지 않아서 해당 application이 종료되면 메모리에 있던 데이터들은 다시 읽어들일 수 없다.
- 데이터를 장기간동안 저장 및 보존하기 위해서 데이터베이스를 사용한다.
RDBMS(Relational DataBase Management System)란?
- 관계형 데이터 모델에 기초를 둔 데이터베이스 시스템
- 관게형 데이터란 데이터를 서로 상호관련성을 가진 형태로 표현한 데이터를 말한다.
- 모든 데이터들은 2차원 테이블로 표현되며 각각의 테이블은 column과 row로 구성된다.
- column(행)은 테이블의 각 항목이고, row(열)는 각 항목들의 실제 값들을 이야기 한다.
- 각 row는 자신만의 고유키(Primary Key)가 존재하며 이 교유키를 통해서 해당 로우를 찾거나 인용하게 된다.
- 각각의 테이블들은 서로 상호 관련성을 가지고 서로 연결될 수 있으며, 크게 3가지 종류가 있다.(one to one, one to many, many to many)
- 대표적인 관게형 데이터베이스에는 MySQL과 PostgreSQL이 있다.
1. 테이블의 관계
One To One
- 테이블 A의 row와 테이블 B의 row가 정확히 일대일 매칭이 되는 관계를 one to one 관계라고 한다.
One To Many
- 테이블 A의 row가 테이블 B의 여러 row와 연결이 되는 관계를 one to many 관계라고 한다.
- 각 고객은 여러 제품을 구매할 수 있지만 구매된 제품의 주인은 오직 한 고객뿐이다.
Many To Many
- 테이블 A의 여러 row가 테이블 B의 여러 row와 연결이 되는 관계를 many to many 관계라고 한다.
- 책은 여러 작가에 의해 쓰일 수 있고 작가들은 여러 책을 쓸 수 있다.
어떻게 테이블과 테이블은 연결할까?
- Forign key(외부키)라는 개념을 사용한다.
- 위의 one to one 에서 user_profiles 테이블의 user_id 컬럼은 users 테이블에 걸려있는 외부키라고 지정한다.
- 데이터베이스에게 user_id의 값은 users 테이블의 id 값이며 그러므로 users 테이블의 id 컬럼에 존재하는 값만 생성될 수 있다.
왜 관계형 테이블을 사용할까?
- 하나의 테이블에 모든 정보를 다 넣으면 동일한 정보들이 불필요하게 중복되어 저장된다.
- 중복된 데이터를 저장하지 않음으로 디스크를 더 효율적으로 쓰고, 서로 같은 데이터이지만 부분적으로 틀린 데이터가 생기는 문제가 없어진다.(normalization)
ACID(Atomaticity, Consistency, Isolation, Durability)
- 원자성(automicity): transiction과 관련된 작업들이 부분적으로 실행되다가 중단되지 않는 것을 보장하는 능력
- 일관성(consistency): transiction이 실행을 성공적으로 완료하면 언제나 일관성있는 데이터베이스 상태로 유지한다.
- 고립성(isolation): transiction 수행시 다른 transiction의 연산작업이 끼어들지 못하도록 보장하는 것으로 transiction 밖에 있는 어떤 연산도 중간 단계의 데이터를 볼 수 없다.
- 지속성(durability): 성공적으로 수행된 transiction은 시스템 문제, DB 일관성 체크 등을 하더라도 유지되어 영원히 반영되어야 한다.transiction은 로그에 모든 것이 저장된 후에만 commit 상태로 간주될 수 있으므로 전형적으로 모든 transiction은 로그로 남고 시스템 장애 발생 전 상태로 되돌릴 수 있다.
Transiction
- ACID를 제공함으로 일련의 작업들을 한번에 하나의 unit으로 실행하는 transiction 기능을 제공한다.
- transiction은 일련의 작업들이 하나의 작업처럼 취급되어서 모두 다 성공하거나 모두 다 실패하는것
NoSQL 데이터베이스
- 비관계형 타입의 데이터를 저장할때 주로 사용되는 데이터베이스 시스템으로 관계형 데이터베이스와 다르게 데이터들을 저장하기 전에 정의 할 필요가 없다. 즉 테이블을 정의하지 않아도된다.
- MongoDB, Redis, Cassandra 등이 가장 대표적인 NoSQL 데이터 베이스이다.
SQL(RDBMS) VS NoSQL
SQL
- 장점
- 관계형 데이터베이스는 데이터를 더 효율적으로 그리고 체계적으로 저장할 수 있고 관리 할 수 있다.
- 미리 저장하는 데이터들의 구조(테이블 스키마)를 정의 함으로 데이터의 완전성이 보장된다.
- transaction
- 단점
- 테이블을 미리 정의해야 함으로 테이블 구조 변화 등에 덜 유연하다.
- 테이블 구조가 미리 정의 되어 있다보니 단순히 서버를 늘리는것 만으로 확장하기가 쉽지 않고 서버의 성능 자체도 높여야 하며 서버를 늘려서 분산 저장 하는것도 쉽지 않다.
- Scale up (서버의 성능을 높이는것)으로 확장성이 된다.
- 정형화된 데이터들과 데이터의 완전성이 중요한 데이터들을 저장하는데 유리하다.
(ex) 전자상거래 정보. 은행 계좌 정보, 거래 정보)
NoSQL
- 장점
- 테이터 구조를 미리 정의하지 않아도 되기 때문에 저장하는 데이터의 구조 변화에 유연하다.
- 확장하기가 쉽고 테이터의 구조도 유연하다 보니 방대한 양의 데이터를 저장하는데 유리하다.
- 단점
- 데이터의 완전성이 덜 보장되며 트랜잭션이 안되거나 비교적 불안정하다.
- 주로 비정형화 데이터 그리고 완전성이 상대적으로 덜 유리한 데이터를 저장하는데 유리하다.(ex) 로그 데이터)
SQL 기초
- Structured Query Language, MySQL같은 관계형 데이터베이스에서 데이터를 읽거나 생성 및 수정하기 위해서 사용하는 언어
- CRUD(create, read, update, delete)
select
SELECT id, name, age, gender FROM users WHERE name = "아이유"
insert
INSERT INTO users (
id,
name,
age,
gender
) VALUES (
1,
"아이유",
27,
"여자"
), (
2,
"제인",
19,
"여자"
)
update
UPDATE users SET age = 25 WHERE name = "아이유"
delete
DELETE FROM users WHERE gender = "남자"
exist
- 어떠한 조건이 존재 하는지 하지 않는지 확인할 때 사용한다.
ELECT 1
FROM users
WHERE EXISTS (SELECT *
FROM users
WHERE user_name = '아이유');
SELECT lname, fname
FROM customer
WHERE NOT EXISTS (SELECT *
FROM orders
WHERE customers.customer_id = orders.c_id);
join
- Foreign key로 걸려있는 2개의 테이블들을 연결해서 양쪽 테이블에서 모두 row를 읽어들이고 싶을 겨우 join문을 사용한다.(교집합)
- 기본 문법
SELECT
테이블별칭.조회할칼럼,
테이블별칭.조회할칼럼
FROM 기준테이블 별칭
INNER JOIN 조인테이블 별칭 ON 기준테이블별칭.기준키 = 조인테이블별칭.기준키
SELECT
users.id,
users.name,
users.age,
users.gender,
accounts.account_type
FROM users
JOIN accounts ON accounts.id = users.account_id
- 여러 유형들
- (INNER)JOIN: 일반적인 join문으로 기준이 되는 테이블(left table)과 join이 걸리는 테이블(right table) 양쪽 모두에 매칭되는 row만 선택된다.
- LEFT(OUTER)JOIN: 기준이 되는 테이블의 모든 row와 join이 걸리는 테이블 중 left table 과 매칭이 되는 row만 선택된다.
- RIGHT(OUTER)JOIN: join이 걸리는 테이블의 모든 row 와 기준이 되는 테이블에서 right table과 매칭되는 row만 선택된다.
- FULL(OUTER)JOIN : 기준이 되는 테이블과 join이 걸리는 테이블 양쪽 모두의 모든 row를 select한다.
create table
CREATE TABLE accounts(
id INT NOT NULL AUTO_INCREMENT,
account_type VARCHAR(100) NOT NULL,
PRIMARY KEY (id)
);
CREATE TABLE users(
id INT NOT NULL AUTO_INCREMENT,
name VARCHAR(255) NOT NULL,
email VARCHAR(255) NOT NULL,
hashed_password VARCHAR(255) NOT NULL,
account_id INT NOT NULL,
PRIMARY KEY (id),
UNIQUE KEY email (email),
CONSTRAINT `users_account_fkey` FOREIGN KEY (`account_id`) REFERENCES `accounts` (`id`)
);