코드스테이츠 31일차

안형준·2022년 6월 9일
0

코드스테이츠

목록 보기
31/32
post-thumbnail

학습 목표

  • SQL 주요 문법을 이해할 수 있다.
    • 조회, 삽입, 갱신, 삭제 구문을 자유자재로 사용할 수 있다.
    • 조회시 다양한 조건을 걸어 원하는 정보만 조회할 수 있다.
    • 통계를 위한 쿼리를 만들 수 있다.
  • 스키마 디자인을 할 수 있다.
    • 앱에 필요한 테이블과 필드, 그리고 관계를 부여할 수 있다.
  • 1:N, N:N 관계를 이해하고, 데이터베이스에서 테이블을 조작할 수 있다.
    • Foreign Key, Primary Key에 대해 이해할 수 있다.
👻SQL(Structured Query Language)
데이터베이스의 필요성
1. In-Memory
예기치 못한 상황이 발생하면 데이터를 보호할 수 없고, 프로그램이 종료된 상태라면 데이터를 원하는 시간에 받아올 수 없으며, 데이터의 수명이 프로그램의 수명에 의존하게 된다.
2. File I/O
File I/O는 파일을 읽는 방식으로 작동하는 형태를 말한다.
In-Memory에 비해 데이터를 저장하는 방식으로 적절해 보이지만, 이러한 방식도 한계가 존재한다.
* 데이터가 필요할 때마다 전체 파일을 매번 읽어야 한다. 파일의 크기가 커질수록 이 작업은 버겁고, 비효율적이게 된다.
* 파일이 손상되거나 여러 개의 파일들을 동시에 다뤄야 하거나 하는 등 복잡하고 데이터량이 많아질수록 데이터를 불러들이는 작업이 점점 힘들어 진다.

SQL은 데이터베이스 언어로, 주로 관계형 데이터베이스에서 사용한다.(MySQL, Oracle, SQLite, PostgreSQL)

쿼리란 ?
쿼리는 저장되어 있는 데이터를 필터하기 위한 질의문으로도 볼 수 있다.
데이터베이스에 쿼리를 보내 원하는 데이터를 가져오거나 삽입할 수 있다.

또한 SQL은 데이터가 구조화된(structured) 테이블을 사용하는 데이터베이스에서 활용할 수 있다.
SQL을 사용할 수 있는 데이터베이스와 달리, 데이터의 구조가 고정되어 있지 않은 데이터베이스를 NoSQL이라고 한다.
관계형 데이터베이스와는 달리, 테이블을 사용하지 않고 데이터를 다른 형태로 저장한다.(Ex. MongoDB와 같은 문서지향 데이터베이스)

데이터베이스 관련 명령어

데이터베이스 생성
CREATE DATABASE 데이터베이스_이름;

데이터베이스 사용
USE 데이터베이스_이름;

테이블 생성
USE 를 이용해 데이터베이스를 선택했다면, 이제 테이블을 만들 수 있다.
CREATE TABLE user (
  id int PRIMARY KEY AUTO_INCREMENT,
  name varchar(255),
  email varchar(255)
);

테이블 정보 확인
DESCRIBE user;

SQL 명령어

SELECT
SELECT는 데이터셋에 포함될 특성을 특정한다.
SELECT 'hello world'

FROM
테이블과 관련한 작업을 할 경우 반드시 입력해야 하는 명령어이며, FROM 뒤에는 결과를 도출해낼 데이터베이스 테이블을 명시한다.
SELECT 특성_1
FROM 테이블_이름

SELECT *
FROM 테이블_이름
* 는 와일드카드 (wildcard) 로 전부 선택할 때에 사용된다.

WHERE
필터 역할을 하는 쿼리문
SELECT 특성_1, 특성_2
FROM 테이블_이름
WHERE 특성_1 = "특정 값"

특정 값을 제외한 값을 찾을 때
SELECT 특성_1, 특성_2
FROM 테이블_이름
WHERE 특성_2 <> "특정 값"

그 외에 대소비교, 특정 값과 비슷한 값들을 필터, 리스트의 값들과 일치하는 데이터를 필터, 값이 없는 경우 'NULL' 을 찾을 때, 값이 없는 경우를 제외할 때 등 다양하게 활용할 수 있다.

ALTER TABLE
컬럼을 추가해주고, 삭제해주는 역할 (수정)

INSERT INTO 
테이블에 데이터 추가하기
INSERT INTO table1

UPDATE SET 
DB 값 수정하기
UPDATE [테이블] SET [열] = '변경할값' WHERE [조건]

DELETE FROM
데이터 삭제하기

DROP DATABASE(TABLE)
DROP 명령어는 데이블 전체를 삭제, 공간, 객체를 삭제한다. 삭제 후 절대 되돌릴 수 없다.

TRUNCATE TABLE
테이블의 있는 데이터를 한번에 제거하며, 테이블이 최초 생성 되었을 시의 Storage만 남기고, 데이터가 담겨있던 Storage는 Release된다. 즉, CREATE TABLE을 한 직후의 상태로 만든다.) 또한 이미 지운 데이터를 되돌릴 수 없다.

LIKE
문자열의 패턴을 검색하는 데 사용
SELECT * FROM 테이블 WHERE 컬럼 LIKE ‘PATTERN’
패턴에는 %와 _가 사용되는데 %는 모든 문자라는 의미이고, _는 한글자라는 의미이다.
%자바% == 앞뒤에 어떤 글자가 있던 ‘자바’라는 문자가 있는 것을 출력한다.
%자바 == 앞에 어떤 글자가 있던 ‘자바’라는 문자로 끝나는 것을 출력한다.
자바% == 뒤에 어떤 글자가 있던 맨 앞에 있는 글자가 ‘자바’인것을 출력한다.
_자바% == 뒤에 어떤 글자가 있던 맨 앞에 한 글자 뒤에 ‘자바’인것을 출력한다. 이를 활용하면 앞에 __를 붙인다면 두 글자 뒤에 있는 것을 출력하게 된다.(__자바__ 이런식으로도 가능)
[acs]% a, c, s로 시작하는 것을 출력한다.
[a-f]% a에서 f로 시작하는 것을 출력한다.

IN 연산자
WHERE 컬럼 IN (‘a’, ‘b’, ‘c’)
a, b, c 중 하나라도 일치하는 것이 있으면 출력한다.
WHERE 컬럼 NOT IN (‘a’, ‘b’, ‘c’)
a, b, c 세 값은 제외하고  출력한다.

BETWEEN
BEETWEEN A AND B
조건 A에서 조건 B 사이의 값을 출력한다.

ALIAS
ALIAS 는 값에 별칭을 주어 접근을 별칭 형태로 할 수 있도록 하는 역할을 한다.
ColumnName AS 컬럼명칭 : 컬럼에 별칭 부여하기
TableName AS 테이블명칭 : 테이블에 별칭 부여하기


ORDER BY
돌려받는 데이터 결과를 어떤 기준으로 정렬하여 출력할지 결정한다.
기본값은 오름차순 내림차순은 아래와 같이 입력한다.
SELECT *
FROM 테이블_이름
ORDER BY 특성_1 DESC

LIMIT
결과로 출력할 데이터의 갯수를 정할 수 있으며, 쿼리문에서 사용할 때에는 가장 마지막에 추가한다.
SELECT *
FROM 테이블_이름
LIMIT 200

DISTINCT
유니크한 값을 받고 싶을 때에는 SELECT DISTINCT 를 사용할 수 있다.
SELECT DISTINCT 특성_1
FROM 테이블_이름

GROUP BY
유형별로 갯수를 알고 싶을 때는 컬럼에 데이터를 그룹화 할 수 있는 GROUP BY를 사용한다.
SELECT 컬럼 FROM 테이블 GROUP BY 그룹화할 컬럼;


👻JOIN
* INNER JOIN(내부 조인)은 두 테이블을 조인할 때, 두 테이블에 모두 지정한 열의 데이터가 있어야 한다.
* OUTER JOIN(외부 조인)은 두 테이블을 조인할 때, 1개의 테이블에만 데이터가 있어도 결과가 나온다.
* CROSS JOIN(상호 조인)은 한쪽 테이블의 모든 행과 다른 쪽 테이블의 모든 행을 조인하는 기능이다.
* SELF JOIN(자체 조인)은 자신이 자신과 조인한다는 의미로, 1개의 테이블을 사용한다.

INNER JOIN
둘 이상의 테이블을 서로 공통된 부분을 기준으로 연결
 SELECT < 목록>
 FROM < 번째 테이블>
          INNER JOIN < 번째 테이블>
          ON <조인될 조건>
 [WHERE 검색 조건]

OUTER JOIN
내부 조인은 두 테이블에 모두 데이터가 있어야만 결과가 나오지만, 외부 조인은 한쪽에만 데이터가 있어도 결과가 나온다.
* LEFT OUTER JOIN: 왼쪽 테이블의 모든 값이 출력되는 조인
* RIGHT OUTER JOIN: 오른쪽 테이블의 모든 값이 출력되는 조인
* FULL OUTER JOIN: 왼쪽 또는 오른쪽 테이블의 모든 값이 출력되는 조인
 SELECT < 목록>
 FROM < 번째 테이블(LEFT 테이블)>
          <LEFT | RIGHT | FULL> OUTER JOIN < 번째 테이블(RIGHT 테이블)>
           ON <조인될 조건>
 [WHERE 검색 조건]

CROSS JOIN(상호 조인)
한쪽 테이블의 모든 행과 다른 쪽 테이블의 모든 행을 조인시키는 기능
상호 조인 결과의 전체 행 개수는 두 테이블의 각 행의 개수를 곱한 수만큼 된다.(카티션 곱(CARTESIAN PRODUCT)
 SELECT * 
 FROM < 번째 테이블>
           CROSS JOIN < 번째 테이블>

SELF JOIN(자체 조인)
자체 조인은 자기 자신과 조인하므로 1개의 테이블을 사용한다.
 SELECT < 목록>
 FROM <테이블> 별칭A
          INNER JOIN <테이블> 별칭B
          ON <조인될 조건>
 [WHERE 검색 조건]

👻SQL Functions
MIN() 최소값 함수
SELECT MIN(칼럼명)
FROM 테이블명

MAX() 최대값 함수
SELECT MAX(칼럼명)
FROM 테이블명

COUNT() 특정 컬럼의 숫자를 확인하는 함수

AVG() 평균을 구하는 함수

SUM() 총합을 구하는 함수


👻ACID

트랜잭션
트랜잭션이란 여러 개의 작업을 하나로 묶은 실행 유닛이다.
각 트랜잭션은 하나의 특정 작업으로 시작을 해 묶여 있는 모든 작업들을 다 완료해야 정상적으로 종료한다.
만약 여러 작업 중에서 단 하나의 작업이라도 실패하면, 이 트랜잭션에 속한 모든 작업을 실패한 것으로 판단한다.

ACID
ACID는 데이터베이스 내에서 일어나는 하나의 트랜잭션(transaction)의 안전성을 보장하기 위해 필요한 성질인데 4가지로 나눌 수 있다.

1. Atomicity(원자성)
원자성은 하나의 트랜잭션에 속해있는 모든 작업이 전부 성공하거나 전부 실패해서 결과를 예측할 수 있어야한다.
예를 들어 A계좌에서 B계좌로 입금한다고 보자.
계좌이체를 하려는데 A 계좌에서는 출금이 이뤄지고, B 계좌에 입금되지 않으면 A 계좌에서 출금된 돈은 세상에서 사라지는 돈이 된다.
이처럼 B 계좌에 입금하는 작업에 실패한다면 계좌 A에서 출금하는 작업을 포함하여 모든 작업이 실패로 돌아가야 한다는 것이 Atomicity(원자성)이다.
원자성을 지켰다면 입금 과정이 성공적으로 완료 되었겠지만 그렇지 않으면(둘 중 하나의 작업이라도 실패한다면), 하나의 단위로 묶여있는 모든 작업이 실패하게 만들어 기존 데이터를 보호한다.
SQL에서도 마찬가지로 특정 쿼리를 실행했는데 부분적으로 실패하는 부분이 있다면, 전부 실패하도록 구현되어 있다.

2. Consistency(일관성)
 두 번째는 데이터베이스의 상태가 일관되어야 한다는 성질이다.
즉 트랜잭션이 일어난 이후의 데이터베이스는 데이터베이스의 제약이나 규칙을 만족해야 한다는 뜻이다.
Ex)
* 이름 없는 새로운 고객을 추가하는 쿼리
* 기존 고객의 이름을 삭제하는 쿼리
위 예시는 '이름이 있어야 한다' 라는 제약을 위반한다. 따라서 예시 트랜잭션이 일어난 이후의 데이터베이스는 일관되지 않는 상태를 가지게 된다.

3. Isolation(격리성, 고립성)
Isolation(격리성) 은 모든 트랜잭션은 다른 트랜잭션으로부터 독립되어야 한다 는 뜻이다.
예를 들어 게좌에 만 원이 있다고 가정하자.
이 계좌로부터 계좌 B로 6천 원을, 계좌 C로 6천 원을 동시에 계좌 이체하는 경우, 계좌 B에 먼저 송금한 뒤 계좌 C에 보내는 결과와 동일해야 한다.
동시에 트랜잭션을 실행한다고 해서 계좌 B와 C에 각각 6천 원씩 송금하여 마이너스 통장이 되는 것이 아니다.
격리성을 지키는 각 트랜젝션은 철저히 독립적이기 때문에, 다른 트랜젝션의 작업 내용을 알 수 없다.
또한 독립적이기 때문에 트랜잭션이 동시에 실행될 때와 연속으로 실행될 때의 데이터베이스 상태가 동일해야 한다.

4. Durability(지속성)
Durability(지속성)는 하나의 트랜잭션이 성공적으로 수행되었다면, 해당 트랜잭션에 대한 로그가 남아야하는데, 만약 런타임 오류나 시스템 오류가 발생하더라도, 해당 기록은 영구적이어야 한다는 뜻이다.
예를 들어 은행에서 게좌이체를 성공적으로 실행한 뒤에, 해당 은행 데이터베이스에 오류가 발생해 종료되더라도 계좌이체 내역은 기록으로 남아야한다.
마찬가지로 계좌이체를 로그로 기록하기 전에 시스템 오류 등에 의해 종료가 된다면, 해당 이체 내역은 실패로 돌아가고 각 계좌들은 계좌이체 이전 상태들로 돌아가게 된다.

👻SQL(구조화 쿼리 언어) vs. NoSQL(비구조화 쿼리 언어)
 데이터베이스는 크게 관계형 데이터베이스와 비관계형 데이터베이스로 구분된다.
관계형 데이터베이스는 SQL을 기반으로 하고, 비관계형 데이터베이스는 NoSQL로 데이터를 다룬다.
이 둘은 만들어진 방식, 저장하는 정보의 종류, 그리고 저장하는 방법 등에 차이가 있다.

관계형 데이터베이스(Ex. MySQL, Oracle, SQLite, PostgresSQL, MariaDB)
행(row)과 열(column)로 구성된 테이블에 데이터를 저장
각 열은 하나의 속성에 대한 정보를 저장하고, 행에는 각 열의 데이터 형식에 맞는 데이터가 저장한다.
특정한 형식을 지키기 때문에, 데이터를 정확히 입력했다면 데이터를 사용할 때에는 매우 수월해 원하는 정보를 쉽게 쿼리할 수 있다는 장점도 있다.

NoSQL(Ex. MongoDB,Casandra)
주로 데이터가 고정되어 있지 않은 데이터베이스를 가리킨다.
NoSQL에서는 데이터를 읽어올 때 스키마에 따라 데이터를 읽어오는데, 이러한 방식을 'schema on read'라고도 한다.

Key-Value 타입 : 속성을 Key-Value의 쌍으로 나타내는 데이터를 배열의 형태로 저장한다.
Ex) Redis, Dynamo

문서형(Document) 데이터베이스 : 데이터를 테이블이 아닌 문서처럼 저장하는 데이터베이스를 의미한다.
JSON과 유사한 형식의 데이터를 문서화하여 저장한다. (Ex. MongoDB)

Wide-Column 데이터베이스 : 데이터베이스의 열(column)에 대한 데이터를 집중적으로 관리하는 데이터베이스이다.
key-value 형식으로 데이터가 저장되고, 컬럼 패밀리(column families)라고 하는 열의 집합체 단위로 데이터를 처리할 수 있다.
주로  규모가 큰 데이터 분석에 주로 사용된다. (Ex. Cassandra, HBase)

그래프(Graph) 데이터베이스 : 자료구조의 그래프와 비슷한 형식으로 데이터 간의 관계를 구성하는 데이터베이스이다.
노드(nodes)에 속성별(entities)로 데이터를 저장한다. (Ex. Neo4J, InfiniteGraph)

👻SQL 기반의 데이터베이스와 NoSQL 데이터베이스의 차이점
데이터 저장(Storage)
* NoSQL은 key-value, document, wide-column, graph 등의 방식으로 데이터를 저장한다.
* 관계형 데이터베이스는 SQL을 이용해서 데이터를 테이블에 저장합니다. 미리 작성된 스키마를 기반으로 정해진 형식에 맞게 데이터를 저장해야 한다.
스키마(Schema)
* SQL을 사용하려면, 고정된 형식의 스키마가 필요히다. 다시 말해, 처리하려는 데이터 속성별로 열(column)에 대한 정보를 미리 정해두어야 힌다. 스키마는 나중에 변경할 수 있지만, 이 경우 데이터베이스 전체를 수정하거나 오프라인(down-time)으로 전환할 필요가 있다.
* NoSQL은 관계형 데이터베이스보다 동적으로 스키마의 형태를 관리할 수 있다. 행을 추가할 때 즉시 새로운 열을 추가할 수 있고, 개별 속성에 대해서 모든 열에 대한 데이터를 반드시 입력하지 않아도 된다.
쿼리(Querying)
* 쿼리는 데이터베이스에 대해서 정보를 요청하는 질의문이다. 관계형 데이터베이스는 테이블의 형식과 테이블간의 관계에 맞춰 데이터를 요청해야 한다. 그래서 정보를 요청할 때, SQL과 같이 구조화된 쿼리 언어를 사용한다.
* 비관계형 데이터베이스의 쿼리는 데이터 그룹 자체를 조회하는 것에 초점을 두고 있습니다. 그래서 구조화 되지 않은 쿼리 언어로도 데이터 요청이 가능하다. UnQL(UnStructured Query Language)이라고 말하기도 한다.
확장성(Scalability)
* 일반적으로 SQL 기반의 관계형 데이터베이스는 수직적으로 확장한다. 높은 메모리, CPU를 사용하는 확장이라고도 한다. 데이터베이스가 구축된 하드웨어의 성능을 많이 이용하기 때문에 비용이 많이 든다. 여러 서버에 걸쳐서 데이터베이스의 관계를 정의할 수 있지만, 매우 복잡하고 시간이 많이 소모된다.
* NoSQL로 구성된 데이터베이스는 수평적으로 확장한다. 보다 값싼 서버 증설, 또는 클라우드 서비스 이용하는 확장이라고도 한다. NoSQL 데이터베이스를 위한 서버를 추가적으로 구축하면, 많은 트래픽을 보다 편리하게 처리할 수 있다. 그리고 저렴한 범용 하드웨어나 클라우드 기반의 인스턴스에 NoSQL 데이터베이스를 호스팅할 수 있어서, 수직적 확장보다 상대적으로 비용이 저렴하다.

그래서 둘 중 무엇을 써야 하는 건가요?
이 점에 대해서는 상황에 따라 사용하는 방식이 달라지기 때문에 무엇이 더 뛰어나다고 보기는 어렵다.
NoSQL 기반의 비관계형 데이터베이스가 확장성이나 속도면에서 더 뛰어나다. 그러나 고차원으로 구조화된 SQL 기반의 데이터베이스가 더 좋은 성능을 보여주는 서비스도 있다.

SQL 기반의 관계형 데이터베이스를 사용하는 케이스
1. 데이터베이스의 ACID 성질을 준수해야 하는 경우
2. 소프트웨어에 사용되는 데이터가 구조적이고 일관적인 경우

NoSQL 기반의 비관계형 데이터베이스를 사용하는 케이스
1. 데이터의 구조가 거의 또는 전혀 없는 대용량의 데이터를 저장하는 경우
2. 클라우드 컴퓨팅 및 저장공간을 최대한 활용하는 경우
3. 빠르게 서비스를 구축하는 과정에서 데이터 구조를 자주 업데이트 하는 경우

오늘은 데이터베이스에 대한 개념을 학습했다.
코드스테이츠에 들어오기 전에 따로 데이터베이스에 대한 개념을 조금은 학습했었다.
하지만 깊숙한 부분까지는 학습하지 않았던 터라 학습하는 데에 쉽다는 느낌보다는 다시 한 번 공부하는 기분이 들었다.
알고리즘이 너무 어려웠던 탓일까 지금 데이터베이스를 학습하는 것만 해도 너무 즐겁고 행복하다.
이제 곧 스프링을 시작할텐데 알고리즘 때 느꼈던 불안한 기분이 또 다시 들까봐 무섭다.
가능한 예습도 하면서 대비를 철저히 해둬야 할 것 같다.
오늘도 고생했어 내일도 파이팅!

profile
개발 공부

0개의 댓글